summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ObsoleteFiles.inc6
-rw-r--r--bin/date/date.17
-rw-r--r--bin/date/date.c10
-rw-r--r--contrib/netcat/netcat.c280
-rw-r--r--contrib/ntp/ntpd/ntp_control.c2
-rwxr-xr-xetc/rc.d/hostid2
-rw-r--r--include/Makefile25
-rw-r--r--lib/libc/gen/directory.38
-rw-r--r--lib/libc/gen/telldir.c16
-rw-r--r--lib/libc/stdlib/Makefile.inc5
-rw-r--r--lib/libc/stdlib/Symbol.map1
-rw-r--r--lib/libc/stdlib/reallocarray.3142
-rw-r--r--lib/libc/stdlib/reallocarray.c42
-rw-r--r--lib/libvmmapi/vmmapi.c34
-rw-r--r--lib/libvmmapi/vmmapi.h11
-rw-r--r--libexec/rtld-elf/debug.h4
-rw-r--r--libexec/rtld-elf/rtld.c4
-rw-r--r--release/arm/BEAGLEBONE.conf19
-rw-r--r--release/arm/PANDABOARD.conf19
-rw-r--r--release/arm/RPI-B.conf22
-rw-r--r--release/arm/RPI2.conf22
-rw-r--r--release/arm/WANDBOARD.conf23
-rwxr-xr-xrelease/release.sh14
-rw-r--r--release/tools/arm.subr14
-rw-r--r--share/man/man4/acpi.423
-rw-r--r--share/man/man4/usb_quirk.45
-rw-r--r--share/man/man9/Makefile1
-rw-r--r--share/man/man9/namei.918
-rw-r--r--share/mk/src.libnames.mk6
-rw-r--r--sys/amd64/acpica/acpi_machdep.c7
-rw-r--r--sys/amd64/amd64/apic_vector.S20
-rw-r--r--sys/amd64/amd64/cpu_switch.S75
-rw-r--r--sys/amd64/amd64/genassym.c2
-rw-r--r--sys/amd64/amd64/machdep.c1
-rw-r--r--sys/amd64/amd64/mp_machdep.c254
-rw-r--r--sys/amd64/amd64/pmap.c341
-rw-r--r--sys/amd64/amd64/vm_machdep.c2
-rw-r--r--sys/amd64/include/cpufunc.h5
-rw-r--r--sys/amd64/include/md_var.h1
-rw-r--r--sys/amd64/include/pcpu.h4
-rw-r--r--sys/amd64/include/pmap.h15
-rw-r--r--sys/amd64/include/smp.h19
-rw-r--r--sys/amd64/include/vmm.h17
-rw-r--r--sys/amd64/include/vmm_instruction_emul.h12
-rw-r--r--sys/amd64/vmm/vmm.c23
-rw-r--r--sys/amd64/vmm/vmm_dev.c14
-rw-r--r--sys/amd64/vmm/vmm_instruction_emul.c123
-rw-r--r--sys/arm/amlogic/aml8726/aml8726_pic.c6
-rw-r--r--sys/arm/arm/machdep.c52
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c3
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2836.c50
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2836_mp.c207
-rw-r--r--sys/arm/broadcom/bcm2835/files.bcm28361
-rw-r--r--sys/arm/broadcom/bcm2835/std.bcm28361
-rw-r--r--sys/arm/conf/AML87262
-rw-r--r--sys/arm/conf/APALIS-IMX62
-rw-r--r--sys/arm/conf/ARMADAXP4
-rw-r--r--sys/arm/conf/ARNDALE2
-rw-r--r--sys/arm/conf/ARNDALE-OCTA2
-rw-r--r--sys/arm/conf/ATMEL4
-rw-r--r--sys/arm/conf/AVILA6
-rw-r--r--sys/arm/conf/BEAGLEBONE4
-rw-r--r--sys/arm/conf/BWCT4
-rw-r--r--sys/arm/conf/CAMBRIA6
-rw-r--r--sys/arm/conf/CHROMEBOOK2
-rw-r--r--sys/arm/conf/CHROMEBOOK-PEACH-PIT2
-rw-r--r--sys/arm/conf/CHROMEBOOK-SNOW2
-rw-r--r--sys/arm/conf/CHROMEBOOK-SPRING2
-rw-r--r--sys/arm/conf/CNS11XXNAS4
-rw-r--r--sys/arm/conf/COLIBRI-VF502
-rw-r--r--sys/arm/conf/COSMIC2
-rw-r--r--sys/arm/conf/CRB4
-rw-r--r--sys/arm/conf/CUBIEBOARD4
-rw-r--r--sys/arm/conf/CUBIEBOARD24
-rw-r--r--sys/arm/conf/DB-78XXX4
-rw-r--r--sys/arm/conf/DB-88F5XXX4
-rw-r--r--sys/arm/conf/DB-88F6XXX4
-rw-r--r--sys/arm/conf/DIGI-CCWMX532
-rw-r--r--sys/arm/conf/DOCKSTAR4
-rw-r--r--sys/arm/conf/DREAMPLUG-10014
-rw-r--r--sys/arm/conf/EA32504
-rw-r--r--sys/arm/conf/EB92004
-rw-r--r--sys/arm/conf/EFIKA_MX2
-rw-r--r--sys/arm/conf/EP802194
-rw-r--r--sys/arm/conf/ETHERNUT54
-rw-r--r--sys/arm/conf/EXYNOS5.common2
-rw-r--r--sys/arm/conf/EXYNOS52504
-rw-r--r--sys/arm/conf/EXYNOS54204
-rw-r--r--sys/arm/conf/GUMSTIX4
-rw-r--r--sys/arm/conf/HL2004
-rw-r--r--sys/arm/conf/HL2014
-rw-r--r--sys/arm/conf/IMX532
-rw-r--r--sys/arm/conf/IMX53-QSB2
-rw-r--r--sys/arm/conf/IMX62
-rw-r--r--sys/arm/conf/IQ312444
-rw-r--r--sys/arm/conf/KB920X4
-rw-r--r--sys/arm/conf/LN2410SBC2
-rw-r--r--sys/arm/conf/NSLU6
-rw-r--r--sys/arm/conf/PANDABOARD2
-rw-r--r--sys/arm/conf/QILA9G204
-rw-r--r--sys/arm/conf/QUARTZ2
-rw-r--r--sys/arm/conf/RADXA2
-rw-r--r--sys/arm/conf/RADXA-LITE2
-rw-r--r--sys/arm/conf/RK31884
-rw-r--r--sys/arm/conf/RPI-B6
-rw-r--r--sys/arm/conf/RPI29
-rw-r--r--sys/arm/conf/SAM9260EK4
-rw-r--r--sys/arm/conf/SAM9G20EK4
-rw-r--r--sys/arm/conf/SAM9X25EK4
-rw-r--r--sys/arm/conf/SHEEVAPLUG4
-rw-r--r--sys/arm/conf/SN9G454
-rw-r--r--sys/arm/conf/SOCKIT.common2
-rw-r--r--sys/arm/conf/TS78004
-rw-r--r--sys/arm/conf/VERSATILEPB2
-rw-r--r--sys/arm/conf/VIRT4
-rw-r--r--sys/arm/conf/VYBRID4
-rw-r--r--sys/arm/conf/ZEDBOARD2
-rw-r--r--sys/arm/include/armreg.h3
-rw-r--r--sys/arm/include/cpu-v6.h7
-rw-r--r--sys/arm/include/pl310.h2
-rw-r--r--sys/arm/include/sysreg.h1
-rw-r--r--sys/arm/ti/ti_i2c.c11
-rw-r--r--sys/arm64/arm64/busdma_bounce.c1080
-rw-r--r--sys/arm64/arm64/busdma_machdep.c305
-rw-r--r--sys/arm64/include/bus_dma_impl.h96
-rw-r--r--sys/boot/arm/uboot/ldscript.arm18
-rw-r--r--sys/boot/fdt/dts/arm/odroidc1.dts7
-rw-r--r--sys/boot/fdt/dts/arm/rpi2.dts18
-rw-r--r--sys/boot/fdt/dts/arm/vsatv102-m6.dts6
-rw-r--r--sys/cam/ctl/ctl_backend_block.c6
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c3
-rw-r--r--sys/conf/NOTES1
-rw-r--r--sys/conf/files1
-rw-r--r--sys/conf/files.arm641
-rw-r--r--sys/conf/options1
-rw-r--r--sys/dev/acpica/acpi.c2
-rw-r--r--sys/dev/acpica/acpi_cpu.c176
-rw-r--r--sys/dev/acpica/acpi_package.c22
-rw-r--r--sys/dev/acpica/acpi_timer.c3
-rw-r--r--sys/dev/acpica/acpivar.h2
-rw-r--r--sys/dev/hwpmc/hwpmc_amd.c46
-rw-r--r--sys/dev/hwpmc/hwpmc_armv7.c12
-rw-r--r--sys/dev/hwpmc/hwpmc_core.c64
-rw-r--r--sys/dev/hwpmc/hwpmc_e500.c12
-rw-r--r--sys/dev/hwpmc/hwpmc_intel.c8
-rw-r--r--sys/dev/hwpmc/hwpmc_logging.c40
-rw-r--r--sys/dev/hwpmc/hwpmc_mips.c12
-rw-r--r--sys/dev/hwpmc/hwpmc_mips24k.c2
-rw-r--r--sys/dev/hwpmc/hwpmc_mips74k.c2
-rw-r--r--sys/dev/hwpmc/hwpmc_mod.c166
-rw-r--r--sys/dev/hwpmc/hwpmc_mpc7xxx.c12
-rw-r--r--sys/dev/hwpmc/hwpmc_octeon.c3
-rw-r--r--sys/dev/hwpmc/hwpmc_piv.c49
-rw-r--r--sys/dev/hwpmc/hwpmc_ppc970.c12
-rw-r--r--sys/dev/hwpmc/hwpmc_ppro.c26
-rw-r--r--sys/dev/hwpmc/hwpmc_soft.c6
-rw-r--r--sys/dev/hwpmc/hwpmc_tsc.c4
-rw-r--r--sys/dev/hwpmc/hwpmc_uncore.c48
-rw-r--r--sys/dev/hwpmc/hwpmc_xscale.c12
-rw-r--r--sys/dev/iicbus/iicbus.c102
-rw-r--r--sys/dev/iicbus/iicbus.h1
-rw-r--r--sys/dev/ofw/ofw_iicbus.c17
-rw-r--r--sys/dev/sound/pcm/channel.c147
-rw-r--r--sys/dev/sound/pcm/channel.h1
-rw-r--r--sys/dev/sound/pcm/feeder_chain.c35
-rw-r--r--sys/dev/sound/pcm/sound.h8
-rw-r--r--sys/dev/sound/usb/uaudio.c57
-rw-r--r--sys/dev/usb/quirk/usb_quirk.c4
-rw-r--r--sys/dev/usb/quirk/usb_quirk.h1
-rw-r--r--sys/dev/usb/usb_device.c6
-rw-r--r--sys/dev/usb/usb_msctest.c190
-rw-r--r--sys/dev/usb/usb_msctest.h2
-rw-r--r--sys/dev/usb/usbdevs4
-rw-r--r--sys/dev/usb/wlan/if_urtwn.c27
-rw-r--r--sys/dev/usb/wlan/if_urtwnreg.h2
-rw-r--r--sys/dev/vt/vt.h5
-rw-r--r--sys/dev/vt/vt_core.c40
-rw-r--r--sys/dev/xen/blkback/blkback.c11
-rw-r--r--sys/dev/xen/grant_table/grant_table.c5
-rw-r--r--sys/dev/xen/netback/netback.c9
-rw-r--r--sys/dev/xen/privcmd/privcmd.c26
-rw-r--r--sys/i386/acpica/acpi_machdep.c7
-rw-r--r--sys/i386/include/md_var.h1
-rw-r--r--sys/kern/kern_fork.c3
-rw-r--r--sys/kern/kern_malloc.c6
-rw-r--r--sys/kern/kern_sig.c2
-rw-r--r--sys/kern/kern_thread.c23
-rw-r--r--sys/kern/uipc_mbuf.c1
-rw-r--r--sys/net/if_me.c2
-rw-r--r--sys/netinet/sctp_auth.c4
-rw-r--r--sys/netinet6/ip6_ipsec.c29
-rw-r--r--sys/netinet6/ip6_output.c14
-rw-r--r--sys/sys/param.h2
-rw-r--r--sys/sys/pmc.h45
-rw-r--r--sys/vm/default_pager.c1
-rw-r--r--sys/vm/device_pager.c2
-rw-r--r--sys/vm/phys_pager.c2
-rw-r--r--sys/vm/sg_pager.c2
-rw-r--r--sys/vm/swap_pager.c2
-rw-r--r--sys/vm/uma.h3
-rw-r--r--sys/vm/uma_core.c42
-rw-r--r--sys/vm/vm_meter.c16
-rw-r--r--sys/vm/vm_object.c31
-rw-r--r--sys/vm/vm_pageout.c7
-rw-r--r--sys/vm/vm_phys.c47
-rw-r--r--sys/vm/vm_phys.h1
-rw-r--r--sys/x86/acpica/srat.c126
-rw-r--r--sys/x86/include/acpica_machdep.h1
-rw-r--r--sys/x86/include/specialreg.h1
-rw-r--r--sys/x86/x86/cpu_machdep.c35
-rw-r--r--sys/x86/xen/xen_apic.c20
-rw-r--r--sys/x86/xen/xenpv.c84
-rw-r--r--sys/xen/xen-os.h7
-rw-r--r--sys/xen/xenmem/xenmem_if.m95
-rw-r--r--tools/build/mk/OptionalObsoleteFiles.inc10
-rw-r--r--usr.bin/checknr/checknr.c2
-rw-r--r--usr.bin/col/col.c117
-rw-r--r--usr.bin/netstat/if.c16
-rw-r--r--usr.sbin/bhyve/inout.c8
-rw-r--r--usr.sbin/bhyve/pci_ahci.c13
-rw-r--r--usr.sbin/bhyve/pci_virtio_net.c25
-rw-r--r--usr.sbin/bhyve/task_switch.c151
-rw-r--r--usr.sbin/pmcstat/pmcstat.87
-rw-r--r--usr.sbin/pmcstat/pmcstat.c59
-rw-r--r--usr.sbin/pmcstat/pmcstat_log.c4
-rw-r--r--usr.sbin/pw/Makefile2
-rw-r--r--usr.sbin/pw/fileupd.c21
-rw-r--r--usr.sbin/pw/grupd.c4
-rw-r--r--usr.sbin/pw/pw_conf.c94
-rw-r--r--usr.sbin/pw/pw_nis.c3
-rw-r--r--usr.sbin/pw/pw_user.c8
231 files changed, 4633 insertions, 1840 deletions
diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc
index 3897b2a..1f762f4 100644
--- a/ObsoleteFiles.inc
+++ b/ObsoleteFiles.inc
@@ -38,6 +38,8 @@
# xargs -n1 | sort | uniq -d;
# done
+# 20150506
+OLD_FILES+=usr/share/man/man9/NDHASGIANT.9.gz
# 20150504
OLD_LIBS+=usr/lib32/private/libatf-c++.so.2
OLD_LIBS+=usr/lib32/private/libbsdstat.so.1
@@ -430,10 +432,6 @@ OLD_FILES+=usr/lib/debug/usr/lib32/i18n
OLD_FILES+=usr/lib/debug/usr/lib32/private
# 20141015: OpenSSL 1.0.1j import
OLD_FILES+=usr/share/openssl/man/man3/CMS_sign_add1_signer.3.gz
-.if ${MK_GCC} == "no"
-# 20141009: gperf disabled by default
-OLD_FILES+=usr/bin/gperf
-.endif
# 20140922: sleepq_calc_signal_retval.9 and sleepq_catch_signals.9 removed
OLD_FILES+=usr/share/man/man9/sleepq_calc_signal_retval.9.gz
OLD_FILES+=usr/share/man/man9/sleepq_catch_signals.9.gz
diff --git a/bin/date/date.1 b/bin/date/date.1
index 5e9e664..dd791ec 100644
--- a/bin/date/date.1
+++ b/bin/date/date.1
@@ -32,7 +32,7 @@
.\" @(#)date.1 8.3 (Berkeley) 4/28/95
.\" $FreeBSD$
.\"
-.Dd April 26, 2014
+.Dd May 7, 2015
.Dt DATE 1
.Os
.Sh NAME
@@ -41,7 +41,7 @@
.Sh SYNOPSIS
.Nm
.Op Fl jRu
-.Op Fl r Ar seconds
+.Op Fl r Ar seconds | Ar filename
.Oo
.Fl v
.Sm off
@@ -150,6 +150,9 @@ is the number of seconds since the Epoch
see
.Xr time 3 ) ,
and can be specified in decimal, octal, or hex.
+.It Fl r Ar filename
+Print the date and time of the last modification of
+.Ar filename .
.It Fl t Ar minutes_west
Set the system's value for minutes west of
.Tn GMT .
diff --git a/bin/date/date.c b/bin/date/date.c
index 2c09848..9ae6502 100644
--- a/bin/date/date.c
+++ b/bin/date/date.c
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/time.h>
+#include <sys/stat.h>
#include <ctype.h>
#include <err.h>
@@ -85,6 +86,7 @@ main(int argc, char *argv[])
struct vary *v;
const struct vary *badv;
struct tm lt;
+ struct stat sb;
v = NULL;
fmt = NULL;
@@ -116,8 +118,12 @@ main(int argc, char *argv[])
case 'r': /* user specified seconds */
rflag = 1;
tval = strtoq(optarg, &tmp, 0);
- if (*tmp != 0)
- usage();
+ if (*tmp != 0) {
+ if (stat(optarg, &sb) == 0)
+ tval = sb.st_mtim.tv_sec;
+ else
+ usage();
+ }
break;
case 't': /* minutes west of UTC */
/* error check; don't allow "PST" */
diff --git a/contrib/netcat/netcat.c b/contrib/netcat/netcat.c
index bb853c9..041fff8 100644
--- a/contrib/netcat/netcat.c
+++ b/contrib/netcat/netcat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: netcat.c,v 1.122 2014/07/20 01:38:40 guenther Exp $ */
+/* $OpenBSD: netcat.c,v 1.127 2015/02/14 22:40:22 jca Exp $ */
/*
* Copyright (c) 2001 Eric Jackson <ericj@monkey.org>
*
@@ -42,7 +42,6 @@
#include <sys/un.h>
#include <netinet/in.h>
-#include <netinet/in_systm.h>
#ifdef IPSEC
#include <netipsec/ipsec.h>
#endif
@@ -73,6 +72,12 @@
#define PORT_MAX_LEN 6
#define UNIX_DG_TMP_SOCKET_SIZE 19
+#define POLL_STDIN 0
+#define POLL_NETOUT 1
+#define POLL_NETIN 2
+#define POLL_STDOUT 3
+#define BUFSIZE 16384
+
/* Command Line Options */
int dflag; /* detached, no stdin */
int Fflag; /* fdpass sock to stdout */
@@ -117,10 +122,12 @@ int udptest(int);
int unix_bind(char *);
int unix_connect(char *);
int unix_listen(char *);
-void set_common_sockopts(int);
+void set_common_sockopts(int, int);
int map_tos(char *, int *);
void report_connect(const struct sockaddr *, socklen_t);
void usage(int);
+ssize_t drainbuf(int, unsigned char *, size_t *);
+ssize_t fillbuf(int, unsigned char *, size_t *);
#ifdef IPSEC
void add_ipsec_policy(int, char *);
@@ -436,7 +443,7 @@ main(int argc, char *argv[])
&len);
if (connfd == -1) {
/* For now, all errnos are fatal */
- err(1, "accept");
+ err(1, "accept");
}
if (vflag)
report_connect((struct sockaddr *)&cliaddr, len);
@@ -663,7 +670,7 @@ remote_connect(const char *host, const char *port, struct addrinfo hints)
freeaddrinfo(ares);
}
- set_common_sockopts(s);
+ set_common_sockopts(s, res0->ai_family);
if (timeout_connect(s, res0->ai_addr, res0->ai_addrlen) == 0)
break;
@@ -767,6 +774,8 @@ local_listen(char *host, char *port, struct addrinfo hints)
err(1, "disable TCP options");
}
+ set_common_sockopts(s, res0->ai_family);
+
if (bind(s, (struct sockaddr *)res0->ai_addr,
res0->ai_addrlen) == 0)
break;
@@ -790,68 +799,224 @@ local_listen(char *host, char *port, struct addrinfo hints)
* Loop that polls on the network file descriptor and stdin.
*/
void
-readwrite(int nfd)
+readwrite(int net_fd)
{
- struct pollfd pfd[2];
- unsigned char buf[16 * 1024];
- int n, wfd = fileno(stdin);
- int lfd = fileno(stdout);
- int plen;
-
- plen = sizeof(buf);
-
- /* Setup Network FD */
- pfd[0].fd = nfd;
- pfd[0].events = POLLIN;
-
- /* Set up STDIN FD. */
- pfd[1].fd = wfd;
- pfd[1].events = POLLIN;
+ struct pollfd pfd[4];
+ int stdin_fd = STDIN_FILENO;
+ int stdout_fd = STDOUT_FILENO;
+ unsigned char netinbuf[BUFSIZE];
+ size_t netinbufpos = 0;
+ unsigned char stdinbuf[BUFSIZE];
+ size_t stdinbufpos = 0;
+ int n, num_fds;
+ ssize_t ret;
+
+ /* don't read from stdin if requested */
+ if (dflag)
+ stdin_fd = -1;
+
+ /* stdin */
+ pfd[POLL_STDIN].fd = stdin_fd;
+ pfd[POLL_STDIN].events = POLLIN;
+
+ /* network out */
+ pfd[POLL_NETOUT].fd = net_fd;
+ pfd[POLL_NETOUT].events = 0;
+
+ /* network in */
+ pfd[POLL_NETIN].fd = net_fd;
+ pfd[POLL_NETIN].events = POLLIN;
+
+ /* stdout */
+ pfd[POLL_STDOUT].fd = stdout_fd;
+ pfd[POLL_STDOUT].events = 0;
+
+ while (1) {
+ /* both inputs are gone, buffers are empty, we are done */
+ if (pfd[POLL_STDIN].fd == -1 && pfd[POLL_NETIN].fd == -1
+ && stdinbufpos == 0 && netinbufpos == 0) {
+ close(net_fd);
+ return;
+ }
+ /* both outputs are gone, we can't continue */
+ if (pfd[POLL_NETOUT].fd == -1 && pfd[POLL_STDOUT].fd == -1) {
+ close(net_fd);
+ return;
+ }
+ /* listen and net in gone, queues empty, done */
+ if (lflag && pfd[POLL_NETIN].fd == -1
+ && stdinbufpos == 0 && netinbufpos == 0) {
+ close(net_fd);
+ return;
+ }
- while (pfd[0].fd != -1) {
+ /* help says -i is for "wait between lines sent". We read and
+ * write arbitrary amounts of data, and we don't want to start
+ * scanning for newlines, so this is as good as it gets */
if (iflag)
sleep(iflag);
- if ((n = poll(pfd, 2 - dflag, timeout)) < 0) {
- int saved_errno = errno;
- close(nfd);
- errc(1, saved_errno, "Polling Error");
+ /* poll */
+ num_fds = poll(pfd, 4, timeout);
+
+ /* treat poll errors */
+ if (num_fds == -1) {
+ close(net_fd);
+ err(1, "polling error");
}
- if (n == 0)
+ /* timeout happened */
+ if (num_fds == 0)
return;
- if (pfd[0].revents & POLLIN) {
- if ((n = read(nfd, buf, plen)) < 0)
- return;
- else if (n == 0) {
- shutdown(nfd, SHUT_RD);
- pfd[0].fd = -1;
- pfd[0].events = 0;
- } else {
- if (tflag)
- atelnet(nfd, buf, n);
- if (atomicio(vwrite, lfd, buf, n) != n)
- return;
+ /* treat socket error conditions */
+ for (n = 0; n < 4; n++) {
+ if (pfd[n].revents & (POLLERR|POLLNVAL)) {
+ pfd[n].fd = -1;
}
}
+ /* reading is possible after HUP */
+ if (pfd[POLL_STDIN].events & POLLIN &&
+ pfd[POLL_STDIN].revents & POLLHUP &&
+ ! (pfd[POLL_STDIN].revents & POLLIN))
+ pfd[POLL_STDIN].fd = -1;
+
+ if (pfd[POLL_NETIN].events & POLLIN &&
+ pfd[POLL_NETIN].revents & POLLHUP &&
+ ! (pfd[POLL_NETIN].revents & POLLIN))
+ pfd[POLL_NETIN].fd = -1;
+
+ if (pfd[POLL_NETOUT].revents & POLLHUP) {
+ if (Nflag)
+ shutdown(pfd[POLL_NETOUT].fd, SHUT_WR);
+ pfd[POLL_NETOUT].fd = -1;
+ }
+ /* if HUP, stop watching stdout */
+ if (pfd[POLL_STDOUT].revents & POLLHUP)
+ pfd[POLL_STDOUT].fd = -1;
+ /* if no net out, stop watching stdin */
+ if (pfd[POLL_NETOUT].fd == -1)
+ pfd[POLL_STDIN].fd = -1;
+ /* if no stdout, stop watching net in */
+ if (pfd[POLL_STDOUT].fd == -1) {
+ if (pfd[POLL_NETIN].fd != -1)
+ shutdown(pfd[POLL_NETIN].fd, SHUT_RD);
+ pfd[POLL_NETIN].fd = -1;
+ }
- if (!dflag && pfd[1].revents & POLLIN) {
- if ((n = read(wfd, buf, plen)) < 0)
- return;
- else if (n == 0) {
- if (Nflag)
- shutdown(nfd, SHUT_WR);
- pfd[1].fd = -1;
- pfd[1].events = 0;
- } else {
- if (atomicio(vwrite, nfd, buf, n) != n)
- return;
+ /* try to read from stdin */
+ if (pfd[POLL_STDIN].revents & POLLIN && stdinbufpos < BUFSIZE) {
+ ret = fillbuf(pfd[POLL_STDIN].fd, stdinbuf,
+ &stdinbufpos);
+ /* error or eof on stdin - remove from pfd */
+ if (ret == 0 || ret == -1)
+ pfd[POLL_STDIN].fd = -1;
+ /* read something - poll net out */
+ if (stdinbufpos > 0)
+ pfd[POLL_NETOUT].events = POLLOUT;
+ /* filled buffer - remove self from polling */
+ if (stdinbufpos == BUFSIZE)
+ pfd[POLL_STDIN].events = 0;
+ }
+ /* try to write to network */
+ if (pfd[POLL_NETOUT].revents & POLLOUT && stdinbufpos > 0) {
+ ret = drainbuf(pfd[POLL_NETOUT].fd, stdinbuf,
+ &stdinbufpos);
+ if (ret == -1)
+ pfd[POLL_NETOUT].fd = -1;
+ /* buffer empty - remove self from polling */
+ if (stdinbufpos == 0)
+ pfd[POLL_NETOUT].events = 0;
+ /* buffer no longer full - poll stdin again */
+ if (stdinbufpos < BUFSIZE)
+ pfd[POLL_STDIN].events = POLLIN;
+ }
+ /* try to read from network */
+ if (pfd[POLL_NETIN].revents & POLLIN && netinbufpos < BUFSIZE) {
+ ret = fillbuf(pfd[POLL_NETIN].fd, netinbuf,
+ &netinbufpos);
+ if (ret == -1)
+ pfd[POLL_NETIN].fd = -1;
+ /* eof on net in - remove from pfd */
+ if (ret == 0) {
+ shutdown(pfd[POLL_NETIN].fd, SHUT_RD);
+ pfd[POLL_NETIN].fd = -1;
}
+ /* read something - poll stdout */
+ if (netinbufpos > 0)
+ pfd[POLL_STDOUT].events = POLLOUT;
+ /* filled buffer - remove self from polling */
+ if (netinbufpos == BUFSIZE)
+ pfd[POLL_NETIN].events = 0;
+ /* handle telnet */
+ if (tflag)
+ atelnet(pfd[POLL_NETIN].fd, netinbuf,
+ netinbufpos);
+ }
+ /* try to write to stdout */
+ if (pfd[POLL_STDOUT].revents & POLLOUT && netinbufpos > 0) {
+ ret = drainbuf(pfd[POLL_STDOUT].fd, netinbuf,
+ &netinbufpos);
+ if (ret == -1)
+ pfd[POLL_STDOUT].fd = -1;
+ /* buffer empty - remove self from polling */
+ if (netinbufpos == 0)
+ pfd[POLL_STDOUT].events = 0;
+ /* buffer no longer full - poll net in again */
+ if (netinbufpos < BUFSIZE)
+ pfd[POLL_NETIN].events = POLLIN;
+ }
+
+ /* stdin gone and queue empty? */
+ if (pfd[POLL_STDIN].fd == -1 && stdinbufpos == 0) {
+ if (pfd[POLL_NETOUT].fd != -1 && Nflag)
+ shutdown(pfd[POLL_NETOUT].fd, SHUT_WR);
+ pfd[POLL_NETOUT].fd = -1;
+ }
+ /* net in gone and queue empty? */
+ if (pfd[POLL_NETIN].fd == -1 && netinbufpos == 0) {
+ pfd[POLL_STDOUT].fd = -1;
}
}
}
+ssize_t
+drainbuf(int fd, unsigned char *buf, size_t *bufpos)
+{
+ ssize_t n;
+ ssize_t adjust;
+
+ n = write(fd, buf, *bufpos);
+ /* don't treat EAGAIN, EINTR as error */
+ if (n == -1 && (errno == EAGAIN || errno == EINTR))
+ n = -2;
+ if (n <= 0)
+ return n;
+ /* adjust buffer */
+ adjust = *bufpos - n;
+ if (adjust > 0)
+ memmove(buf, buf + n, adjust);
+ *bufpos -= n;
+ return n;
+}
+
+
+ssize_t
+fillbuf(int fd, unsigned char *buf, size_t *bufpos)
+{
+ size_t num = BUFSIZE - *bufpos;
+ ssize_t n;
+
+ n = read(fd, buf + *bufpos, num);
+ /* don't treat EAGAIN, EINTR as error */
+ if (n == -1 && (errno == EAGAIN || errno == EINTR))
+ n = -2;
+ if (n <= 0)
+ return n;
+ *bufpos += n;
+ return n;
+}
+
/*
* fdpass()
* Pass the connected file descriptor to stdout and exit.
@@ -1025,7 +1190,7 @@ udptest(int s)
}
void
-set_common_sockopts(int s)
+set_common_sockopts(int s, int af)
{
int x = 1;
@@ -1040,8 +1205,17 @@ set_common_sockopts(int s)
err(1, NULL);
}
if (Tflag != -1) {
- if (setsockopt(s, IPPROTO_IP, IP_TOS,
- &Tflag, sizeof(Tflag)) == -1)
+ int proto, option;
+
+ if (af == AF_INET6) {
+ proto = IPPROTO_IPV6;
+ option = IPV6_TCLASS;
+ } else {
+ proto = IPPROTO_IP;
+ option = IP_TOS;
+ }
+
+ if (setsockopt(s, proto, option, &Tflag, sizeof(Tflag)) == -1)
err(1, "set IP ToS");
}
if (Iflag) {
diff --git a/contrib/ntp/ntpd/ntp_control.c b/contrib/ntp/ntpd/ntp_control.c
index 91ab39a..2a1cf22 100644
--- a/contrib/ntp/ntpd/ntp_control.c
+++ b/contrib/ntp/ntpd/ntp_control.c
@@ -4,7 +4,7 @@
*/
/*
- * $FreeBSD: projects/release-arm-redux/contrib/ntp/ntpd/ntp_control.c 276071 2014-12-22 18:54:55Z delphij $
+ * $FreeBSD: head/contrib/ntp/ntpd/ntp_control.c 276071 2014-12-22 18:54:55Z delphij $
*/
#ifdef HAVE_CONFIG_H
diff --git a/etc/rc.d/hostid b/etc/rc.d/hostid
index 281b241..a26cbc0 100755
--- a/etc/rc.d/hostid
+++ b/etc/rc.d/hostid
@@ -58,7 +58,7 @@ hostid_set()
valid_hostid()
{
- uuid=$1
+ uuid=$(echo $1 | tr '[:upper:]' '[:lower:]')
x="[0-9a-f]"
y=$x$x$x$x
diff --git a/include/Makefile b/include/Makefile
index fe29186..d7badd7 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -57,18 +57,14 @@ LSUBDIRS= cam/ata cam/scsi \
security/mac_mls security/mac_partition \
ufs/ffs ufs/ufs
-.if ${MK_USB} != "no"
-LSUBDIRS+= dev/usb
-.endif
-
LSUBSUBDIRS= dev/mpt/mpilib
-.if ${MK_CUSE} != "no"
-LSUBDIRS+= fs/cuse
+.if ${MK_BLUETOOTH} != "no"
+LSUBSUBDIRS+= netgraph/bluetooth/include
.endif
-.if ${MACHINE_ARCH} == "powerpc" || ${MACHINE_ARCH} == "powerpc64"
-_dev_powermac_nvram= dev/powermac_nvram
+.if ${MK_CUSE} != "no"
+LSUBDIRS+= fs/cuse
.endif
.if ${MK_GSSAPI} != "no"
@@ -80,15 +76,18 @@ INCS+= gssapi.h
INCS+= hesiod.h
.endif
-.if ${MK_BLUETOOTH} != "no"
-LSUBSUBDIRS+= netgraph/bluetooth/include
-.endif
-
# Handle the #define aliases for libiconv
.if ${MK_ICONV} == "yes"
INCS+= iconv.h
.endif
-
+
+.if ${MK_USB} != "no"
+LSUBDIRS+= dev/usb
+.endif
+
+.if ${MACHINE_ARCH} == "powerpc" || ${MACHINE_ARCH} == "powerpc64"
+_dev_powermac_nvram= dev/powermac_nvram
+.endif
# Define SHARED to indicate whether you want symbolic links to the system
# source (``symlinks''), or a separate copy (``copies''). ``symlinks'' is
diff --git a/lib/libc/gen/directory.3 b/lib/libc/gen/directory.3
index e1874da..f0d0f4b 100644
--- a/lib/libc/gen/directory.3
+++ b/lib/libc/gen/directory.3
@@ -28,7 +28,7 @@
.\" @(#)directory.3 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
-.Dd July 28, 2014
+.Dd May 6, 2015
.Dt DIRECTORY 3
.Os
.Sh NAME
@@ -263,12 +263,6 @@ function appeared in
function appeared in
.Fx 10.0 .
.Sh BUGS
-The invalidation of
-.Fn telldir
-tokens when calling
-.Fn seekdir
-is non-standard. This is a compile time option.
-.Pp
The behaviour of
.Fn telldir
and
diff --git a/lib/libc/gen/telldir.c b/lib/libc/gen/telldir.c
index 54cab5b..19cd6ee 100644
--- a/lib/libc/gen/telldir.c
+++ b/lib/libc/gen/telldir.c
@@ -101,11 +101,12 @@ _seekdir(dirp, loc)
return;
if (lp->loc_loc == dirp->dd_loc && lp->loc_seek == dirp->dd_seek)
return;
- /* If it's within the same chunk of data, don't bother reloading */
+
+ /* If it's within the same chunk of data, don't bother reloading. */
if (lp->loc_seek == dirp->dd_seek) {
/*
* If we go back to 0 don't make the next readdir
- * trigger a call to getdirentries()
+ * trigger a call to getdirentries().
*/
if (lp->loc_loc == 0)
dirp->dd_flags |= __DTF_SKIPREAD;
@@ -124,10 +125,13 @@ _seekdir(dirp, loc)
}
/*
- * when we do a read and cross a boundary, any telldir we
- * just did will have wrong information in it.
- * We need to move it from "beyond the end of the previous chunk"
- * to "the beginning of the new chunk"
+ * After readdir returns the last entry in a block, a call to telldir
+ * returns a location that is after the end of that last entry.
+ * However, that location doesn't refer to a valid directory entry.
+ * Ideally, the call to telldir would return a location that refers to
+ * the first entry in the next block. That location is not known
+ * until the next block is read, so readdir calls this function after
+ * fetching a new block to fix any such telldir locations.
*/
void
_fixtelldir(DIR *dirp, long oldseek, long oldloc)
diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc
index 57205a7..7cee03a 100644
--- a/lib/libc/stdlib/Makefile.inc
+++ b/lib/libc/stdlib/Makefile.inc
@@ -10,7 +10,8 @@ MISRCS+=_Exit.c a64l.c abort.c abs.c atexit.c atof.c atoi.c atol.c atoll.c \
insque.c l64a.c labs.c ldiv.c llabs.c lldiv.c lsearch.c \
merge.c mergesort_b.c ptsname.c qsort.c qsort_r.c quick_exit.c \
radixsort.c rand.c \
- random.c reallocf.c realpath.c remque.c strfmon.c strtoimax.c \
+ random.c reallocarray.c reallocf.c realpath.c remque.c strfmon.c \
+ strtoimax.c \
strtol.c strtoll.c strtoq.c strtoul.c strtonum.c strtoull.c \
strtoumax.c strtouq.c system.c tdelete.c tfind.c tsearch.c twalk.c
@@ -25,7 +26,7 @@ MAN+= a64l.3 abort.3 abs.3 alloca.3 atexit.3 atof.3 \
hcreate.3 imaxabs.3 imaxdiv.3 insque.3 labs.3 ldiv.3 llabs.3 lldiv.3 \
lsearch.3 memory.3 ptsname.3 qsort.3 \
quick_exit.3 \
- radixsort.3 rand.3 random.3 reallocf.3 \
+ radixsort.3 rand.3 random.3 reallocarray.3 reallocf.3 \
realpath.3 strfmon.3 strtod.3 strtol.3 strtonum.3 strtoul.3 system.3 \
tsearch.3
diff --git a/lib/libc/stdlib/Symbol.map b/lib/libc/stdlib/Symbol.map
index 39eab7d..782023e 100644
--- a/lib/libc/stdlib/Symbol.map
+++ b/lib/libc/stdlib/Symbol.map
@@ -113,6 +113,7 @@ FBSD_1.4 {
hcreate_r;
hdestroy_r;
hsearch_r;
+ reallocarray;
};
FBSDprivate_1.0 {
diff --git a/lib/libc/stdlib/reallocarray.3 b/lib/libc/stdlib/reallocarray.3
new file mode 100644
index 0000000..8e714f4
--- /dev/null
+++ b/lib/libc/stdlib/reallocarray.3
@@ -0,0 +1,142 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" 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 REGENTS 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 REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd May 1, 2015
+.Dt REALLOCARRAY 3
+.Os
+.Sh NAME
+.Nm reallocarray
+.Nd memory reallocation function
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In stdlib.h
+.Ft void *
+.Fn reallocarray "void *ptr" "size_t nmemb" "size_t size"
+.Sh DESCRIPTION
+The
+.Fn reallocarray
+function is similar to the
+.Fn realloc
+function
+except it operates on
+.Fa nmemb
+members of size
+.Fa size
+and checks for integer overflow in the calculation
+.Fa nmemb
+*
+.Fa size .
+.Sh RETURN VALUES
+The
+.Fn reallocarray
+function returns a pointer to the allocated space; otherwise, a
+.Dv NULL
+pointer is returned and
+.Va errno
+is set to
+.Er ENOMEM .
+.Sh EXAMPLES
+Consider
+.Fn reallocarray
+when there is multiplication in the
+.Fa size
+argument of
+.Fn malloc
+or
+.Fn realloc .
+For example, avoid this common idiom as it may lead to integer overflow:
+.Bd -literal -offset indent
+if ((p = malloc(num * size)) == NULL)
+ err(1, "malloc");
+.Ed
+.Pp
+A drop-in replacement is the
+.Ox
+extension
+.Fn reallocarray :
+.Bd -literal -offset indent
+if ((p = reallocarray(NULL, num, size)) == NULL)
+ err(1, "reallocarray");
+.Ed
+.Pp
+When using
+.Fn realloc ,
+be careful to avoid the following idiom:
+.Bd -literal -offset indent
+size += 50;
+if ((p = realloc(p, size)) == NULL)
+ return (NULL);
+.Ed
+.Pp
+Do not adjust the variable describing how much memory has been allocated
+until the allocation has been successful.
+This can cause aberrant program behavior if the incorrect size value is used.
+In most cases, the above sample will also result in a leak of memory.
+As stated earlier, a return value of
+.Dv NULL
+indicates that the old object still remains allocated.
+Better code looks like this:
+.Bd -literal -offset indent
+newsize = size + 50;
+if ((newp = realloc(p, newsize)) == NULL) {
+ free(p);
+ p = NULL;
+ size = 0;
+ return (NULL);
+}
+p = newp;
+size = newsize;
+.Ed
+.Pp
+As with
+.Fn malloc ,
+it is important to ensure the new size value will not overflow;
+i.e. avoid allocations like the following:
+.Bd -literal -offset indent
+if ((newp = realloc(p, num * size)) == NULL) {
+ ...
+.Ed
+.Pp
+Instead, use
+.Fn reallocarray :
+.Bd -literal -offset indent
+if ((newp = reallocarray(p, num, size)) == NULL) {
+ ...
+.Ed
+.Sh SEE ALSO
+.Xr realloc 3
+.Sh HISTORY
+The
+.Fn reallocarray
+function first appeared in
+.Ox 5.6
+and
+.Fx 11.0 .
diff --git a/lib/libc/stdlib/reallocarray.c b/lib/libc/stdlib/reallocarray.c
new file mode 100644
index 0000000..e1e9b7c
--- /dev/null
+++ b/lib/libc/stdlib/reallocarray.c
@@ -0,0 +1,42 @@
+/* $OpenBSD: reallocarray.c,v 1.2 2014/12/08 03:45:00 bcook Exp $ */
+/*
+ * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+/*
+ * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
+ * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
+ */
+#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
+
+void *
+reallocarray(void *optr, size_t nmemb, size_t size)
+{
+
+ if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
+ nmemb > 0 && SIZE_MAX / nmemb < size) {
+ errno = ENOMEM;
+ return (NULL);
+ }
+ return (realloc(optr, size * nmemb));
+}
diff --git a/lib/libvmmapi/vmmapi.c b/lib/libvmmapi/vmmapi.c
index 0c15845..1e6e627 100644
--- a/lib/libvmmapi/vmmapi.c
+++ b/lib/libvmmapi/vmmapi.c
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <machine/specialreg.h>
#include <machine/param.h>
+#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
@@ -958,9 +959,9 @@ vm_get_hpet_capabilities(struct vmctx *ctx, uint32_t *capabilities)
return (error);
}
-static int
-gla2gpa(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging,
- uint64_t gla, int prot, int *fault, uint64_t *gpa)
+int
+vm_gla2gpa(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging,
+ uint64_t gla, int prot, uint64_t *gpa, int *fault)
{
struct vm_gla2gpa gg;
int error;
@@ -979,29 +980,18 @@ gla2gpa(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging,
return (error);
}
-int
-vm_gla2gpa(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging,
- uint64_t gla, int prot, uint64_t *gpa)
-{
- int error, fault;
-
- error = gla2gpa(ctx, vcpu, paging, gla, prot, &fault, gpa);
- if (fault)
- error = fault;
- return (error);
-}
-
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
int
vm_copy_setup(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging,
- uint64_t gla, size_t len, int prot, struct iovec *iov, int iovcnt)
+ uint64_t gla, size_t len, int prot, struct iovec *iov, int iovcnt,
+ int *fault)
{
void *va;
uint64_t gpa;
- int error, fault, i, n, off;
+ int error, i, n, off;
for (i = 0; i < iovcnt; i++) {
iov[i].iov_base = 0;
@@ -1010,18 +1000,16 @@ vm_copy_setup(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging,
while (len) {
assert(iovcnt > 0);
- error = gla2gpa(ctx, vcpu, paging, gla, prot, &fault, &gpa);
- if (error)
- return (-1);
- if (fault)
- return (1);
+ error = vm_gla2gpa(ctx, vcpu, paging, gla, prot, &gpa, fault);
+ if (error || *fault)
+ return (error);
off = gpa & PAGE_MASK;
n = min(len, PAGE_SIZE - off);
va = vm_map_gpa(ctx, gpa, n);
if (va == NULL)
- return (-1);
+ return (EFAULT);
iov->iov_base = va;
iov->iov_len = n;
diff --git a/lib/libvmmapi/vmmapi.h b/lib/libvmmapi/vmmapi.h
index d001cd8..d3ecdc4 100644
--- a/lib/libvmmapi/vmmapi.h
+++ b/lib/libvmmapi/vmmapi.h
@@ -64,7 +64,7 @@ int vm_setup_memory(struct vmctx *ctx, size_t len, enum vm_mmap_style s);
void *vm_map_gpa(struct vmctx *ctx, vm_paddr_t gaddr, size_t len);
int vm_get_gpa_pmap(struct vmctx *, uint64_t gpa, uint64_t *pte, int *num);
int vm_gla2gpa(struct vmctx *, int vcpuid, struct vm_guest_paging *paging,
- uint64_t gla, int prot, uint64_t *gpa);
+ uint64_t gla, int prot, uint64_t *gpa, int *fault);
uint32_t vm_get_lowmem_limit(struct vmctx *ctx);
void vm_set_lowmem_limit(struct vmctx *ctx, uint32_t limit);
void vm_set_memflags(struct vmctx *ctx, int flags);
@@ -131,10 +131,15 @@ int vm_get_hpet_capabilities(struct vmctx *ctx, uint32_t *capabilities);
/*
* Translate the GLA range [gla,gla+len) into GPA segments in 'iov'.
* The 'iovcnt' should be big enough to accomodate all GPA segments.
- * Returns 0 on success, 1 on a guest fault condition and -1 otherwise.
+ *
+ * retval fault Interpretation
+ * 0 0 Success
+ * 0 1 An exception was injected into the guest
+ * EFAULT N/A Error
*/
int vm_copy_setup(struct vmctx *ctx, int vcpu, struct vm_guest_paging *pg,
- uint64_t gla, size_t len, int prot, struct iovec *iov, int iovcnt);
+ uint64_t gla, size_t len, int prot, struct iovec *iov, int iovcnt,
+ int *fault);
void vm_copyin(struct vmctx *ctx, int vcpu, struct iovec *guest_iov,
void *host_dst, size_t len);
void vm_copyout(struct vmctx *ctx, int vcpu, const void *host_src,
diff --git a/libexec/rtld-elf/debug.h b/libexec/rtld-elf/debug.h
index 98fdfb4..ed65227 100644
--- a/libexec/rtld-elf/debug.h
+++ b/libexec/rtld-elf/debug.h
@@ -32,10 +32,6 @@
#ifndef DEBUG_H
#define DEBUG_H 1
-#ifndef __GNUC__
-#error "This file must be compiled with GCC"
-#endif
-
#include <sys/cdefs.h>
#include <string.h>
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 3ac4467..1d91460 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -34,10 +34,6 @@
* John Polstra <jdp@polstra.com>.
*/
-#ifndef __GNUC__
-#error "GCC is needed to compile this file"
-#endif
-
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/mman.h>
diff --git a/release/arm/BEAGLEBONE.conf b/release/arm/BEAGLEBONE.conf
index 87d2ffe..3ae4871 100644
--- a/release/arm/BEAGLEBONE.conf
+++ b/release/arm/BEAGLEBONE.conf
@@ -17,22 +17,21 @@ MD_ARGS="-x 63 -y 255"
NODOC=1
arm_install_uboot() {
- UBOOT_DIR="${CHROOTDIR}/usr/local/share/u-boot/u-boot-beaglebone"
- FATMOUNT="${DESTDIR##${KERNEL}}/fat"
- UFSMOUNT="${DESTDIR##${KERNEL}}/ufs"
+ UBOOT_DIR="/usr/local/share/u-boot/u-boot-beaglebone"
+ FATMOUNT="${DESTDIR%${KERNEL}}/fat"
+ UFSMOUNT="${DESTDIR%${KERNEL}}/ufs"
chroot ${CHROOTDIR} mkdir -p "${FATMOUNT}" "${UFSMOUNT}"
chroot ${CHROOTDIR} mount_msdosfs /dev/${mddev}s1 ${FATMOUNT}
chroot ${CHROOTDIR} mount /dev/${mddev}s2a ${UFSMOUNT}
- cp -p ${UBOOT_DIR}/MLO ${CHROOTDIR}/${FATMOUNT}/MLO
- cp -p ${UBOOT_DIR}/u-boot.img ${CHROOTDIR}/${FATMOUNT}/u-boot.img
- cp -p ${CHROOTDIR}/${UFSMOUNT}/boot/ubldr \
- ${CHROOTDIR}/${FATMOUNT}/ubldr
- touch ${CHROOTDIR}/${UFSMOUNT}/firstboot
+ chroot ${CHROOTDIR} cp -p ${UBOOT_DIR}/MLO ${FATMOUNT}/MLO
+ chroot ${CHROOTDIR} cp -p ${UBOOT_DIR}/u-boot.img ${FATMOUNT}/u-boot.img
+ chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr ${FATMOUNT}/ubldr
+ chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot
sync
umount_loop ${CHROOTDIR}/${FATMOUNT}
umount_loop ${CHROOTDIR}/${UFSMOUNT}
- rmdir ${CHROOTDIR}/${FATMOUNT}
- rmdir ${CHROOTDIR}/${UFSMOUNT}
+ chroot ${CHROOTDIR} rmdir ${FATMOUNT}
+ chroot ${CHROOTDIR} rmdir ${UFSMOUNT}
return 0
}
diff --git a/release/arm/PANDABOARD.conf b/release/arm/PANDABOARD.conf
index 28a4639..b5a120e 100644
--- a/release/arm/PANDABOARD.conf
+++ b/release/arm/PANDABOARD.conf
@@ -17,22 +17,21 @@ FAT_TYPE="12"
MD_ARGS="-x 63 -y 255"
arm_install_uboot() {
- UBOOT_DIR="${CHROOTDIR}/usr/local/share/u-boot/u-boot-pandaboard"
- FATMOUNT="${DESTDIR##${KERNEL}}/fat"
- UFSMOUNT="${DESTDIR##${KERNEL}}/ufs"
+ UBOOT_DIR="/usr/local/share/u-boot/u-boot-pandaboard"
+ FATMOUNT="${DESTDIR%${KERNEL}}/fat"
+ UFSMOUNT="${DESTDIR%${KERNEL}}/ufs"
chroot ${CHROOTDIR} mkdir -p "${FATMOUNT}" "${UFSMOUNT}"
chroot ${CHROOTDIR} mount_msdosfs /dev/${mddev}s1 ${FATMOUNT}
chroot ${CHROOTDIR} mount /dev/${mddev}s2a ${UFSMOUNT}
- cp -p ${UBOOT_DIR}/MLO ${CHROOTDIR}/${FATMOUNT}/MLO
- cp -p ${UBOOT_DIR}/u-boot.img ${CHROOTDIR}/${FATMOUNT}/u-boot.img
- cp -p ${CHROOTDIR}/${UFSMOUNT}/boot/ubldr \
- ${CHROOTDIR}/${FATMOUNT}/ubldr
- touch ${CHROOTDIR}/${UFSMOUNT}/firstboot
+ chroot ${CHROOTDIR} cp -p ${UBOOT_DIR}/MLO ${FATMOUNT}/MLO
+ chroot ${CHROOTDIR} cp -p ${UBOOT_DIR}/u-boot.img ${FATMOUNT}/u-boot.img
+ chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr ${FATMOUNT}/ubldr
+ chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot
sync
umount_loop ${CHROOTDIR}/${FATMOUNT}
umount_loop ${CHROOTDIR}/${UFSMOUNT}
- rmdir ${CHROOTDIR}/${FATMOUNT}
- rmdir ${CHROOTDIR}/${UFSMOUNT}
+ chroot ${CHROOTDIR} rmdir ${FATMOUNT}
+ chroot ${CHROOTDIR} rmdir ${UFSMOUNT}
return 0
}
diff --git a/release/arm/RPI-B.conf b/release/arm/RPI-B.conf
index db3c102..e5abaab 100644
--- a/release/arm/RPI-B.conf
+++ b/release/arm/RPI-B.conf
@@ -17,27 +17,27 @@ MD_ARGS="-x 63 -y 255"
NODOC=1
arm_install_uboot() {
- UBOOT_DIR="${CHROOTDIR}/usr/local/share/u-boot/u-boot-rpi"
+ UBOOT_DIR="/usr/local/share/u-boot/u-boot-rpi"
UBOOT_FILES="bootcode.bin config.txt fixup.dat fixup_cd.dat \
start.elf start_cd.elf u-boot.img"
- FATMOUNT="${DESTDIR##${KERNEL}}/fat"
- UFSMOUNT="${DESTDIR##${KERNEL}}/ufs"
+ FATMOUNT="${DESTDIR%${KERNEL}}/fat"
+ UFSMOUNT="${DESTDIR%${KERNEL}}/ufs"
chroot ${CHROOTDIR} mkdir -p "${FATMOUNT}" "${UFSMOUNT}"
chroot ${CHROOTDIR} mount_msdosfs /dev/${mddev}s1 ${FATMOUNT}
chroot ${CHROOTDIR} mount /dev/${mddev}s2a ${UFSMOUNT}
for _UF in ${UBOOT_FILES}; do
- cp -p ${UBOOT_DIR}/${_UF} ${CHROOTDIR}/${FATMOUNT}/${_UF}
+ chroot ${CHROOTDIR} cp -p ${UBOOT_DIR}/${_UF} \
+ ${FATMOUNT}/${_UF}
done
- cp -p ${CHROOTDIR}/${UFSMOUNT}/boot/ubldr \
- ${CHROOTDIR}/${FATMOUNT}/ubldr
- cp -p ${CHROOTDIR}/${UFSMOUNT}/boot/dtb/rpi.dtb \
- ${CHROOTDIR}/${FATMOUNT}/rpi.dtb
- touch ${CHROOTDIR}/${UFSMOUNT}/firstboot
+ chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr ${FATMOUNT}/ubldr
+ chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/dtb/rpi.dtb \
+ ${FATMOUNT}/rpi.dtb
+ chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot
sync
umount_loop ${CHROOTDIR}/${FATMOUNT}
umount_loop ${CHROOTDIR}/${UFSMOUNT}
- rmdir ${CHROOTDIR}/${FATMOUNT}
- rmdir ${CHROOTDIR}/${UFSMOUNT}
+ chroot ${CHROOTDIR} rmdir ${FATMOUNT}
+ chroot ${CHROOTDIR} rmdir ${UFSMOUNT}
return 0
}
diff --git a/release/arm/RPI2.conf b/release/arm/RPI2.conf
index aadd458..e1d15d1 100644
--- a/release/arm/RPI2.conf
+++ b/release/arm/RPI2.conf
@@ -17,27 +17,27 @@ FAT_TYPE="16"
MD_ARGS="-x 63 -y 255"
arm_install_uboot() {
- UBOOT_DIR="${CHROOTDIR}/usr/local/share/u-boot/u-boot-rpi2"
+ UBOOT_DIR="/usr/local/share/u-boot/u-boot-rpi2"
UBOOT_FILES="bootcode.bin config.txt fixup.dat fixup_cd.dat \
fixup_x.dat start.elf start_cd.elf start_x.elf u-boot.bin"
- FATMOUNT="${DESTDIR##${KERNEL}}/fat"
- UFSMOUNT="${DESTDIR##${KERNEL}}/ufs"
+ FATMOUNT="${DESTDIR%${KERNEL}}/fat"
+ UFSMOUNT="${DESTDIR%${KERNEL}}/ufs"
chroot ${CHROOTDIR} mkdir -p "${FATMOUNT}" "${UFSMOUNT}"
chroot ${CHROOTDIR} mount_msdosfs /dev/${mddev}s1 ${FATMOUNT}
chroot ${CHROOTDIR} mount /dev/${mddev}s2a ${UFSMOUNT}
for _UF in ${UBOOT_FILES}; do
- cp -p ${UBOOT_DIR}/${_UF} ${CHROOTDIR}/${FATMOUNT}/${_UF}
+ chroot ${CHROOTDIR} cp -p ${UBOOT_DIR}/${_UF} \
+ ${FATMOUNT}/${_UF}
done
- cp -p ${CHROOTDIR}/${UFSMOUNT}/boot/ubldr \
- ${CHROOTDIR}/${FATMOUNT}/ubldr
- cp -p ${CHROOTDIR}/${UFSMOUNT}/boot/dtb/rpi2.dtb \
- ${CHROOTDIR}/${FATMOUNT}/rpi2.dtb
- touch ${CHROOTDIR}/${UFSMOUNT}/firstboot
+ chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr ${FATMOUNT}/ubldr
+ chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/dtb/rpi2.dtb \
+ ${FATMOUNT}/rpi2.dtb
+ chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot
sync
umount_loop ${CHROOTDIR}/${FATMOUNT}
umount_loop ${CHROOTDIR}/${UFSMOUNT}
- rmdir ${CHROOTDIR}/${FATMOUNT}
- rmdir ${CHROOTDIR}/${UFSMOUNT}
+ chroot ${CHROOTDIR} rmdir ${FATMOUNT}
+ chroot ${CHROOTDIR} rmdir ${UFSMOUNT}
return 0
}
diff --git a/release/arm/WANDBOARD.conf b/release/arm/WANDBOARD.conf
index 63614d7..42b4523 100644
--- a/release/arm/WANDBOARD.conf
+++ b/release/arm/WANDBOARD.conf
@@ -17,26 +17,25 @@ MD_ARGS="-x 63 -y 255"
NODOC=1
arm_install_uboot() {
- UBOOT_DIR="${CHROOTDIR}/usr/local/share/u-boot/u-boot-wandboard"
+ UBOOT_DIR="/usr/local/share/u-boot/u-boot-wandboard"
UBOOT_FILES="u-boot.imx"
- FATMOUNT="${DESTDIR##${KERNEL}}/fat"
- UFSMOUNT="${DESTDIR##${KERNEL}}/ufs"
- chroot ${CHROOTDIR} dd if=${UBOOT_DIR##${CHROOTDIR}}/${UBOOT_FILES} \
+ FATMOUNT="${DESTDIR%${KERNEL}}/fat"
+ UFSMOUNT="${DESTDIR%${KERNEL}}/ufs"
+ chroot ${CHROOTDIR} dd if=${UBOOT_DIR}/${UBOOT_FILES} \
of=/dev/${mddev} bs=512 seek=2
chroot ${CHROOTDIR} mkdir -p "${FATMOUNT}" "${UFSMOUNT}"
chroot ${CHROOTDIR} mount_msdosfs /dev/${mddev}s1 ${FATMOUNT}
chroot ${CHROOTDIR} mount /dev/${mddev}s2a ${UFSMOUNT}
- cp -p ${CHROOTDIR}/${UFSMOUNT}/boot/ubldr \
- ${CHROOTDIR}/${FATMOUNT}/ubldr
- chroot ${CHROOTDIR} echo \
- 'setenv fdt_file wandboard-quad.dtb; fatload mmc 0:1 11000000 ubldr; bootelf 11000000;' \
- > ${FATMOUNT}/boot.txt
- touch ${CHROOTDIR}/${UFSMOUNT}/firstboot
+ chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr ${FATMOUNT}/ubldr
+ chroot ${CHROOTDIR} /bin/sh -c 'echo \
+ setenv fdt_file wandboard-quad.dtb\; fatload mmc 0:1 11000000 ubldr\; bootelf 11000000\; \
+ > ${FATMOUNT}/boot.txt'
+ chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot
sync
umount_loop ${CHROOTDIR}/${FATMOUNT}
umount_loop ${CHROOTDIR}/${UFSMOUNT}
- rmdir ${CHROOTDIR}/${FATMOUNT}
- rmdir ${CHROOTDIR}/${UFSMOUNT}
+ chroot ${CHROOTDIR} rmdir ${FATMOUNT}
+ chroot ${CHROOTDIR} rmdir ${UFSMOUNT}
return 0
}
diff --git a/release/release.sh b/release/release.sh
index 6c1226c..94a9bb6 100755
--- a/release/release.sh
+++ b/release/release.sh
@@ -56,7 +56,7 @@ usage() {
env_setup() {
# The directory within which the release will be built.
CHROOTDIR="/scratch"
- RELENGDIR="$(realpath $(dirname $(basename ${0})))"
+ RELENGDIR="$(dirname $(realpath ${0}))"
# The default version control system command to obtain the sources.
for _dir in /usr/bin /usr/local/bin; do
@@ -325,11 +325,10 @@ chroot_build_release() {
chroot_arm_armv6_build_release() {
load_target_env
eval chroot ${CHROOTDIR} make -C /usr/src/release obj
- # XXX: In progress.
if [ -e "${RELENGDIR}/tools/${EMBEDDED_TARGET}.subr" ]; then
. "${RELENGDIR}/tools/${EMBEDDED_TARGET}.subr"
fi
- . "${RELENGDIR}/arm/${KERNEL}.conf"
+ [ ! -z "${RELEASECONF}" ] && . "${RELEASECONF}"
WORLDDIR="$(eval chroot ${CHROOTDIR} make -C /usr/src/release -V WORLDDIR)"
OBJDIR="$(eval chroot ${CHROOTDIR} make -C /usr/src/release -V .OBJDIR)"
DESTDIR="${OBJDIR}/${KERNEL}"
@@ -337,14 +336,15 @@ chroot_arm_armv6_build_release() {
OSRELEASE="$(eval chroot ${CHROOTDIR} make -C /usr/src/release \
TARGET=${EMBEDDED_TARGET} TARGET_ARCH=${EMBEDDED_TARGET_ARCH} \
-V OSRELEASE)"
- mkdir -p ${CHROOTDIR}/${DESTDIR}
- truncate -s ${IMAGE_SIZE} ${IMGBASE}
- export mddev=$(mdconfig -f ${IMGBASE} ${MD_ARGS})
+ chroot ${CHROOTDIR} mkdir -p ${DESTDIR}
+ chroot ${CHROOTDIR} truncate -s ${IMAGE_SIZE} ${IMGBASE##${CHROOTDIR}}
+ export mddev=$(chroot ${CHROOTDIR} \
+ mdconfig -f ${IMGBASE##${CHROOTDIR}} ${MD_ARGS})
arm_create_disk
arm_install_base
arm_install_uboot
mdconfig -d -u ${mddev}
- rmdir ${CHROOTDIR}/${DESTDIR}
+ chroot ${CHROOTDIR} rmdir ${DESTDIR}
mv ${IMGBASE} ${CHROOTDIR}/${OBJDIR}/${OSRELEASE}-${KERNEL}.img
chroot ${CHROOTDIR} mkdir -p /R
chroot ${CHROOTDIR} cp -p ${OBJDIR}/${OSRELEASE}-${KERNEL}.img \
diff --git a/release/tools/arm.subr b/release/tools/arm.subr
index c42cf0d..5cc61e3 100644
--- a/release/tools/arm.subr
+++ b/release/tools/arm.subr
@@ -77,6 +77,18 @@ arm_create_disk() {
return 0
}
+arm_create_user() {
+ # Create a default user account 'freebsd' with the password 'freebsd',
+ # and set the default password for the 'root' user to 'root'.
+ chroot ${CHROOTDIR} /usr/sbin/pw groupadd freebsd -g 1001
+ chroot ${CHROOTDIR} /usr/sbin/pw useradd freebsd \
+ -m -M 0755 -w yes -n freebsd -u 1001 -g 1001 -G 0 \
+ -c 'FreeBSD User' -d '/home/freebsd' -s '/bin/csh'
+ chroot ${CHROOTDIR} /usr/sbin/pw usermod root -w yes
+
+ return 0
+}
+
arm_install_base() {
chroot ${CHROOTDIR} mount /dev/${mddev}s2a ${DESTDIR}
eval chroot ${CHROOTDIR} make -C ${WORLDDIR} \
@@ -86,6 +98,8 @@ arm_install_base() {
installworld installkernel distribution
chroot ${CHROOTDIR} mkdir -p ${DESTDIR}/boot/msdos
+ arm_create_user
+
echo '# Custom /etc/fstab for FreeBSD embedded images' \
> ${CHROOTDIR}/${DESTDIR}/etc/fstab
echo "/dev/ufs/rootfs / ufs rw 1 1" \
diff --git a/share/man/man4/acpi.4 b/share/man/man4/acpi.4
index 17cf1cb..8c221be 100644
--- a/share/man/man4/acpi.4
+++ b/share/man/man4/acpi.4
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd June 23, 2014
+.Dd May 9, 2015
.Dt ACPI 4
.Os
.Sh NAME
@@ -69,14 +69,12 @@ them (such as
Enable dumping Debug objects without
.Cd "options ACPI_DEBUG" .
Default is 0, ignore Debug objects.
-.It Va hw.acpi.acline
-AC line state (1 means online, 0 means on battery power).
-.It Va hw.acpi.cpu.cx_usage
+.It Va dev.cpu.N.cx_usage
Debugging information listing the percent of total usage for each sleep state.
The values are reset when
-.Va hw.acpi.cpu.cx_lowest
+.Va dev.cpu.N.cx_lowest
is modified.
-.It Va hw.acpi.cpu.cx_lowest
+.It Va dev.cpu.N.cx_lowest
Lowest Cx state to use for idling the CPU.
A scheduling algorithm will select states between
.Li C1
@@ -111,6 +109,11 @@ semantics as the
state.
Deeper sleeps provide more power savings but increased transition
latency when an interrupt occurs.
+.It Va dev.cpu.N.cx_method
+List of supported CPU idle states and their transition methods, as
+directed by the firmware.
+.It Va hw.acpi.acline
+AC line state (1 means online, 0 means on battery power).
.It Va hw.acpi.disable_on_reboot
Disable ACPI during the reboot process.
Most systems reboot fine with ACPI still enabled, but some require
@@ -374,6 +377,14 @@ typically as a child of a PCI bus.
.Pq Vt device
Supports an ACPI laptop lid switch, which typically puts a
system to sleep.
+.It Li mwait
+.Pq Vt feature
+Do not ask firmware for available x86-vendor specific methods to enter
+.Li Cx
+sleep states.
+Only query and use the generic I/O-based entrance method.
+The knob is provided to work around inconsistencies in the tables
+filled by firmware.
.It Li quirks
.Pq Vt feature
Do not honor quirks.
diff --git a/share/man/man4/usb_quirk.4 b/share/man/man4/usb_quirk.4
index 9352e76..d7686fd 100644
--- a/share/man/man4/usb_quirk.4
+++ b/share/man/man4/usb_quirk.4
@@ -16,7 +16,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd April 21, 2013
+.Dd May 7, 2015
.Dt USB_QUIRK 4
.Os
.Sh NAME
@@ -170,6 +170,9 @@ ejects after Huawei SCSI command
.It UQ_MSC_EJECT_TCT
ejects after TCT SCSI command
.Dv 0x06f504025270
+.It UQ_MSC_DYMO_EJECT
+ejects after HID command
+.Dv 0x1b5a01
.El
.Pp
See
diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile
index 7f79156..11dcb01 100644
--- a/share/man/man9/Makefile
+++ b/share/man/man9/Makefile
@@ -1113,7 +1113,6 @@ MLINKS+=mutex.9 mtx_assert.9 \
mutex.9 mtx_unlock_spin.9 \
mutex.9 mtx_unlock_spin_flags.9
MLINKS+=namei.9 NDFREE.9 \
- namei.9 NDHASGIANT.9 \
namei.9 NDINIT.9
MLINKS+=netisr.9 netisr_clearqdrops.9 \
netisr.9 netisr_default_flow2cpu.9 \
diff --git a/share/man/man9/namei.9 b/share/man/man9/namei.9
index 0bd827f..305665a 100644
--- a/share/man/man9/namei.9
+++ b/share/man/man9/namei.9
@@ -33,14 +33,13 @@
.\"
.\" $FreeBSD$
.\"
-.Dd March 1, 2012
+.Dd May 6, 2015
.Dt NAMEI 9
.Os
.Sh NAME
.Nm namei ,
.Nm NDINIT ,
.Nm NDFREE ,
-.Nm NDHASGIANT
.Nd pathname translation and lookup operations
.Sh SYNOPSIS
.In sys/param.h
@@ -55,8 +54,6 @@
.Fc
.Ft void
.Fn NDFREE "struct nameidata *ndp" "const uint flags"
-.Ft int
-.Fn NDHASGIANT "struct nameidata *ndp"
.Sh DESCRIPTION
The
.Nm
@@ -73,16 +70,6 @@ or
depending on whether the
.Dv LOCKLEAF
flag was specified or not.
-If the
-.Va Giant
-lock is required,
-.Nm
-will acquire it if the caller indicates it is
-.Dv MPSAFE ,
-in which case the caller must later release
-.Va Giant
-based on the results of
-.Fn NDHASGIANT .
.Pp
The
.Fn NDINIT
@@ -362,6 +349,3 @@ In order to solve this for the cases where both
and
.Dv LOCKLEAF
are used, it is necessary to resort to recursive locking.
-.Pp
-Non-MPSAFE file systems exist, requiring callers to conditionally unlock
-.Va Giant .
diff --git a/share/mk/src.libnames.mk b/share/mk/src.libnames.mk
index 192bc00..6279e90 100644
--- a/share/mk/src.libnames.mk
+++ b/share/mk/src.libnames.mk
@@ -24,7 +24,7 @@ _PRIVATELIBS= \
ucl \
unbound
-_INTERNALIBS= \
+_INTERNALLIBS= \
amu \
bsnmptools \
cron \
@@ -49,7 +49,7 @@ _INTERNALIBS= \
_LIBRARIES= \
${_PRIVATELIBS} \
- ${_INTERNALIBS} \
+ ${_INTERNALLIBS} \
alias \
archive \
asn1 \
@@ -243,7 +243,7 @@ LIB${_l:tu}?= ${DESTDIR}${LIBDIR}/libprivate${_l}.a
.endfor
.for _l in ${_LIBRARIES}
-.if ${_INTERNALIBS:M${_l}}
+.if ${_INTERNALLIBS:M${_l}}
LDADD_${_l}_L+= -L${LIB${_l:tu}DIR}
.endif
DPADD_${_l}?= ${LIB${_l:tu}}
diff --git a/sys/amd64/acpica/acpi_machdep.c b/sys/amd64/acpica/acpi_machdep.c
index 049b51bb4e..8f88a00 100644
--- a/sys/amd64/acpica/acpi_machdep.c
+++ b/sys/amd64/acpica/acpi_machdep.c
@@ -87,13 +87,6 @@ acpi_machdep_quirks(int *quirks)
return (0);
}
-void
-acpi_cpu_c1()
-{
-
- __asm __volatile("sti; hlt");
-}
-
/*
* Support for mapping ACPI tables during early boot. Currently this
* uses the crashdump map to map each table. However, the crashdump
diff --git a/sys/amd64/amd64/apic_vector.S b/sys/amd64/amd64/apic_vector.S
index 4455cab..a1279e6 100644
--- a/sys/amd64/amd64/apic_vector.S
+++ b/sys/amd64/amd64/apic_vector.S
@@ -196,8 +196,6 @@ IDTVEC(hv_vmbus_callback)
*/
.text
-#define NAKE_INTR_CS 24
-
SUPERALIGN_TEXT
invltlb_ret:
call as_lapic_eoi
@@ -205,30 +203,28 @@ invltlb_ret:
jmp doreti_iret
SUPERALIGN_TEXT
+IDTVEC(invltlb)
+ PUSH_FRAME
+
+ call invltlb_handler
+ jmp invltlb_ret
+
IDTVEC(invltlb_pcid)
PUSH_FRAME
call invltlb_pcid_handler
jmp invltlb_ret
-
- SUPERALIGN_TEXT
-IDTVEC(invltlb)
+IDTVEC(invltlb_invpcid)
PUSH_FRAME
- call invltlb_handler
+ call invltlb_invpcid_handler
jmp invltlb_ret
/*
* Single page TLB shootdown
*/
.text
- SUPERALIGN_TEXT
-IDTVEC(invlpg_pcid)
- PUSH_FRAME
-
- call invlpg_pcid_handler
- jmp invltlb_ret
SUPERALIGN_TEXT
IDTVEC(invlpg)
diff --git a/sys/amd64/amd64/cpu_switch.S b/sys/amd64/amd64/cpu_switch.S
index eb0ee8b..e292797 100644
--- a/sys/amd64/amd64/cpu_switch.S
+++ b/sys/amd64/amd64/cpu_switch.S
@@ -69,16 +69,10 @@
* %rsi = newtd
*/
ENTRY(cpu_throw)
- movl PCPU(CPUID),%eax
- testq %rdi,%rdi
- jz 1f
- /* release bit from old pm_active */
- movq PCPU(CURPMAP),%rdx
- LK btrl %eax,PM_ACTIVE(%rdx) /* clear old */
-1:
- movq TD_PCB(%rsi),%r8 /* newtd->td_pcb */
- movq PCB_CR3(%r8),%rcx /* new address space */
- jmp swact
+ movq %rsi,%r12
+ movq %rsi,%rdi
+ call pmap_activate_sw
+ jmp sw1
END(cpu_throw)
/*
@@ -132,59 +126,20 @@ ctx_switch_xsave:
xorl %eax,%eax
movq %rax,PCPU(FPCURTHREAD)
3:
-
/* Save is done. Now fire up new thread. Leave old vmspace. */
- movq TD_PCB(%rsi),%r8
-
- /* switch address space */
- movq PCB_CR3(%r8),%rcx
- movq %cr3,%rax
- cmpq %rcx,%rax /* Same address space? */
- jne swinact
- SETLK %rdx, TD_LOCK(%rdi) /* Release the old thread */
- jmp sw1
-swinact:
- movl PCPU(CPUID),%eax
- /* Release bit from old pmap->pm_active */
- movq PCPU(CURPMAP),%r12
- LK btrl %eax,PM_ACTIVE(%r12) /* clear old */
- SETLK %rdx,TD_LOCK(%rdi) /* Release the old thread */
-swact:
- /* Set bit in new pmap->pm_active */
- movq TD_PROC(%rsi),%rdx /* newproc */
- movq P_VMSPACE(%rdx), %rdx
- addq $VM_PMAP,%rdx
- cmpl $-1,PM_PCID(%rdx)
- je 1f
- LK btsl %eax,PM_SAVE(%rdx)
- jnc 1f
- btsq $63,%rcx /* CR3_PCID_SAVE */
- incq PCPU(PM_SAVE_CNT)
-1:
- movq %rcx,%cr3 /* new address space */
- LK btsl %eax,PM_ACTIVE(%rdx) /* set new */
- movq %rdx,PCPU(CURPMAP)
-
- /*
- * We might lose the race and other CPU might have changed
- * the pmap after we set our bit in pmap->pm_save. Recheck.
- * Reload %cr3 with CR3_PCID_SAVE bit cleared if pmap was
- * modified, causing TLB flush for this pcid.
- */
- btrq $63,%rcx
- jnc 1f
- LK btsl %eax,PM_SAVE(%rdx)
- jc 1f
- decq PCPU(PM_SAVE_CNT)
- movq %rcx,%cr3
-1:
-
+ movq %rsi,%r12
+ movq %rdi,%r13
+ movq %rdx,%r15
+ movq %rsi,%rdi
+ callq pmap_activate_sw
+ SETLK %r15,TD_LOCK(%r13) /* Release the old thread */
sw1:
+ movq TD_PCB(%r12),%r8
#if defined(SCHED_ULE) && defined(SMP)
/* Wait for the new thread to become unblocked */
movq $blocked_lock, %rdx
1:
- movq TD_LOCK(%rsi),%rcx
+ movq TD_LOCK(%r12),%rcx
cmpq %rcx, %rdx
pause
je 1b
@@ -195,13 +150,13 @@ sw1:
*/
/* Skip loading user fsbase/gsbase for kthreads */
- testl $TDP_KTHREAD,TD_PFLAGS(%rsi)
+ testl $TDP_KTHREAD,TD_PFLAGS(%r12)
jnz do_kthread
/*
* Load ldt register
*/
- movq TD_PROC(%rsi),%rcx
+ movq TD_PROC(%r12),%rcx
cmpq $0, P_MD+MD_LDT(%rcx)
jne do_ldt
xorl %eax,%eax
@@ -238,7 +193,7 @@ done_tss:
movq %r8,PCPU(CURPCB)
/* Update the TSS_RSP0 pointer for the next interrupt */
movq %r8,COMMON_TSS_RSP0(%rdx)
- movq %rsi,PCPU(CURTHREAD) /* into next thread */
+ movq %r12,PCPU(CURTHREAD) /* into next thread */
/* Test if debug registers should be restored. */
testl $PCB_DBREGS,PCB_FLAGS(%r8)
diff --git a/sys/amd64/amd64/genassym.c b/sys/amd64/amd64/genassym.c
index 3ffefc0..11012c4 100644
--- a/sys/amd64/amd64/genassym.c
+++ b/sys/amd64/amd64/genassym.c
@@ -71,8 +71,6 @@ __FBSDID("$FreeBSD$");
ASSYM(P_VMSPACE, offsetof(struct proc, p_vmspace));
ASSYM(VM_PMAP, offsetof(struct vmspace, vm_pmap));
ASSYM(PM_ACTIVE, offsetof(struct pmap, pm_active));
-ASSYM(PM_SAVE, offsetof(struct pmap, pm_save));
-ASSYM(PM_PCID, offsetof(struct pmap, pm_pcid));
ASSYM(P_MD, offsetof(struct proc, p_md));
ASSYM(MD_LDT, offsetof(struct mdproc, md_ldt));
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 3230937..7cd58b1 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -1718,7 +1718,6 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
/* setup proc 0's pcb */
thread0.td_pcb->pcb_flags = 0;
- thread0.td_pcb->pcb_cr3 = KPML4phys; /* PCID 0 is reserved for kernel */
thread0.td_frame = &proc0_tf;
env = kern_getenv("kernelname");
diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c
index 83ca548..e91e6d5 100644
--- a/sys/amd64/amd64/mp_machdep.c
+++ b/sys/amd64/amd64/mp_machdep.c
@@ -88,12 +88,9 @@ char *doublefault_stack;
char *nmi_stack;
/* Variables needed for SMP tlb shootdown. */
-vm_offset_t smp_tlb_addr2;
-struct invpcid_descr smp_tlb_invpcid;
+static vm_offset_t smp_tlb_addr1, smp_tlb_addr2;
+static pmap_t smp_tlb_pmap;
volatile int smp_tlb_wait;
-uint64_t pcid_cr3;
-pmap_t smp_tlb_pmap;
-extern int invpcid_works;
extern inthand_t IDTVEC(fast_syscall), IDTVEC(fast_syscall32);
@@ -139,14 +136,17 @@ cpu_mp_start(void)
/* Install an inter-CPU IPI for TLB invalidation */
if (pmap_pcid_enabled) {
- setidt(IPI_INVLTLB, IDTVEC(invltlb_pcid), SDT_SYSIGT,
- SEL_KPL, 0);
- setidt(IPI_INVLPG, IDTVEC(invlpg_pcid), SDT_SYSIGT,
- SEL_KPL, 0);
+ if (invpcid_works) {
+ setidt(IPI_INVLTLB, IDTVEC(invltlb_invpcid),
+ SDT_SYSIGT, SEL_KPL, 0);
+ } else {
+ setidt(IPI_INVLTLB, IDTVEC(invltlb_pcid), SDT_SYSIGT,
+ SEL_KPL, 0);
+ }
} else {
setidt(IPI_INVLTLB, IDTVEC(invltlb), SDT_SYSIGT, SEL_KPL, 0);
- setidt(IPI_INVLPG, IDTVEC(invlpg), SDT_SYSIGT, SEL_KPL, 0);
}
+ setidt(IPI_INVLPG, IDTVEC(invlpg), SDT_SYSIGT, SEL_KPL, 0);
setidt(IPI_INVLRNG, IDTVEC(invlrng), SDT_SYSIGT, SEL_KPL, 0);
/* Install an inter-CPU IPI for cache invalidation. */
@@ -242,6 +242,9 @@ init_secondary(void)
pc->pc_gs32p = &gdt[NGDT * cpu + GUGS32_SEL];
pc->pc_ldt = (struct system_segment_descriptor *)&gdt[NGDT * cpu +
GUSERLDT_SEL];
+ pc->pc_curpmap = kernel_pmap;
+ pc->pc_pcid_gen = 1;
+ pc->pc_pcid_next = PMAP_PCID_KERN + 1;
/* Save the per-cpu pointer for use by the NMI handler. */
np->np_pcpu = (register_t) pc;
@@ -407,35 +410,8 @@ start_ap(int apic_id)
}
/*
- * Flush the TLB on all other CPU's
+ * Flush the TLB on other CPU's
*/
-static void
-smp_tlb_shootdown(u_int vector, pmap_t pmap, vm_offset_t addr1,
- vm_offset_t addr2)
-{
- u_int ncpu;
-
- ncpu = mp_ncpus - 1; /* does not shootdown self */
- if (ncpu < 1)
- return; /* no other cpus */
- if (!(read_rflags() & PSL_I))
- panic("%s: interrupts disabled", __func__);
- mtx_lock_spin(&smp_ipi_mtx);
- smp_tlb_invpcid.addr = addr1;
- if (pmap == NULL) {
- smp_tlb_invpcid.pcid = 0;
- } else {
- smp_tlb_invpcid.pcid = pmap->pm_pcid;
- pcid_cr3 = pmap->pm_cr3;
- }
- smp_tlb_addr2 = addr2;
- smp_tlb_pmap = pmap;
- atomic_store_rel_int(&smp_tlb_wait, 0);
- ipi_all_but_self(vector);
- while (smp_tlb_wait < ncpu)
- ia32_pause();
- mtx_unlock_spin(&smp_ipi_mtx);
-}
static void
smp_targeted_tlb_shootdown(cpuset_t mask, u_int vector, pmap_t pmap,
@@ -443,7 +419,11 @@ smp_targeted_tlb_shootdown(cpuset_t mask, u_int vector, pmap_t pmap,
{
int cpu, ncpu, othercpus;
- othercpus = mp_ncpus - 1;
+ othercpus = mp_ncpus - 1; /* does not shootdown self */
+
+ /*
+ * Check for other cpus. Return if none.
+ */
if (CPU_ISFULLSET(&mask)) {
if (othercpus < 1)
return;
@@ -452,16 +432,11 @@ smp_targeted_tlb_shootdown(cpuset_t mask, u_int vector, pmap_t pmap,
if (CPU_EMPTY(&mask))
return;
}
+
if (!(read_rflags() & PSL_I))
panic("%s: interrupts disabled", __func__);
mtx_lock_spin(&smp_ipi_mtx);
- smp_tlb_invpcid.addr = addr1;
- if (pmap == NULL) {
- smp_tlb_invpcid.pcid = 0;
- } else {
- smp_tlb_invpcid.pcid = pmap->pm_pcid;
- pcid_cr3 = pmap->pm_cr3;
- }
+ smp_tlb_addr1 = addr1;
smp_tlb_addr2 = addr2;
smp_tlb_pmap = pmap;
atomic_store_rel_int(&smp_tlb_wait, 0);
@@ -485,65 +460,39 @@ smp_targeted_tlb_shootdown(cpuset_t mask, u_int vector, pmap_t pmap,
}
void
-smp_invlpg(pmap_t pmap, vm_offset_t addr)
-{
-
- if (smp_started) {
- smp_tlb_shootdown(IPI_INVLPG, pmap, addr, 0);
-#ifdef COUNT_XINVLTLB_HITS
- ipi_page++;
-#endif
- }
-}
-
-void
-smp_invlpg_range(pmap_t pmap, vm_offset_t addr1, vm_offset_t addr2)
-{
-
- if (smp_started) {
- smp_tlb_shootdown(IPI_INVLRNG, pmap, addr1, addr2);
-#ifdef COUNT_XINVLTLB_HITS
- ipi_range++;
- ipi_range_size += (addr2 - addr1) / PAGE_SIZE;
-#endif
- }
-}
-
-void
smp_masked_invltlb(cpuset_t mask, pmap_t pmap)
{
if (smp_started) {
smp_targeted_tlb_shootdown(mask, IPI_INVLTLB, pmap, 0, 0);
#ifdef COUNT_XINVLTLB_HITS
- ipi_masked_global++;
+ ipi_global++;
#endif
}
}
void
-smp_masked_invlpg(cpuset_t mask, pmap_t pmap, vm_offset_t addr)
+smp_masked_invlpg(cpuset_t mask, vm_offset_t addr)
{
if (smp_started) {
- smp_targeted_tlb_shootdown(mask, IPI_INVLPG, pmap, addr, 0);
+ smp_targeted_tlb_shootdown(mask, IPI_INVLPG, NULL, addr, 0);
#ifdef COUNT_XINVLTLB_HITS
- ipi_masked_page++;
+ ipi_page++;
#endif
}
}
void
-smp_masked_invlpg_range(cpuset_t mask, pmap_t pmap, vm_offset_t addr1,
- vm_offset_t addr2)
+smp_masked_invlpg_range(cpuset_t mask, vm_offset_t addr1, vm_offset_t addr2)
{
if (smp_started) {
- smp_targeted_tlb_shootdown(mask, IPI_INVLRNG, pmap, addr1,
- addr2);
+ smp_targeted_tlb_shootdown(mask, IPI_INVLRNG, NULL,
+ addr1, addr2);
#ifdef COUNT_XINVLTLB_HITS
- ipi_masked_range++;
- ipi_masked_range_size += (addr2 - addr1) / PAGE_SIZE;
+ ipi_range++;
+ ipi_range_size += (addr2 - addr1) / PAGE_SIZE;
#endif
}
}
@@ -552,19 +501,9 @@ void
smp_cache_flush(void)
{
- if (smp_started)
- smp_tlb_shootdown(IPI_INVLCACHE, NULL, 0, 0);
-}
-
-void
-smp_invltlb(pmap_t pmap)
-{
-
if (smp_started) {
- smp_tlb_shootdown(IPI_INVLTLB, pmap, 0, 0);
-#ifdef COUNT_XINVLTLB_HITS
- ipi_global++;
-#endif
+ smp_targeted_tlb_shootdown(all_cpus, IPI_INVLCACHE, NULL,
+ 0, 0);
}
}
@@ -586,10 +525,10 @@ invltlb_handler(void)
}
void
-invltlb_pcid_handler(void)
+invltlb_invpcid_handler(void)
{
- uint64_t cr3;
- u_int cpuid;
+ struct invpcid_descr d;
+
#ifdef COUNT_XINVLTLB_HITS
xhits_gbl[PCPU_GET(cpuid)]++;
#endif /* COUNT_XINVLTLB_HITS */
@@ -597,49 +536,45 @@ invltlb_pcid_handler(void)
(*ipi_invltlb_counts[PCPU_GET(cpuid)])++;
#endif /* COUNT_IPIS */
- if (smp_tlb_invpcid.pcid != (uint64_t)-1 &&
- smp_tlb_invpcid.pcid != 0) {
- if (invpcid_works) {
- invpcid(&smp_tlb_invpcid, INVPCID_CTX);
- } else {
- /* Otherwise reload %cr3 twice. */
- cr3 = rcr3();
- if (cr3 != pcid_cr3) {
- load_cr3(pcid_cr3);
- cr3 |= CR3_PCID_SAVE;
- }
- load_cr3(cr3);
- }
- } else {
- invltlb_globpcid();
- }
- if (smp_tlb_pmap != NULL) {
- cpuid = PCPU_GET(cpuid);
- if (!CPU_ISSET(cpuid, &smp_tlb_pmap->pm_active))
- CPU_CLR_ATOMIC(cpuid, &smp_tlb_pmap->pm_save);
- }
-
+ d.pcid = smp_tlb_pmap->pm_pcids[PCPU_GET(cpuid)].pm_pcid;
+ d.pad = 0;
+ d.addr = 0;
+ invpcid(&d, smp_tlb_pmap == kernel_pmap ? INVPCID_CTXGLOB :
+ INVPCID_CTX);
atomic_add_int(&smp_tlb_wait, 1);
}
void
-invlpg_handler(void)
+invltlb_pcid_handler(void)
{
#ifdef COUNT_XINVLTLB_HITS
- xhits_pg[PCPU_GET(cpuid)]++;
+ xhits_gbl[PCPU_GET(cpuid)]++;
#endif /* COUNT_XINVLTLB_HITS */
#ifdef COUNT_IPIS
- (*ipi_invlpg_counts[PCPU_GET(cpuid)])++;
+ (*ipi_invltlb_counts[PCPU_GET(cpuid)])++;
#endif /* COUNT_IPIS */
- invlpg(smp_tlb_invpcid.addr);
+ if (smp_tlb_pmap == kernel_pmap) {
+ invltlb_globpcid();
+ } else {
+ /*
+ * The current pmap might not be equal to
+ * smp_tlb_pmap. The clearing of the pm_gen in
+ * pmap_invalidate_all() takes care of TLB
+ * invalidation when switching to the pmap on this
+ * CPU.
+ */
+ if (PCPU_GET(curpmap) == smp_tlb_pmap) {
+ load_cr3(smp_tlb_pmap->pm_cr3 |
+ smp_tlb_pmap->pm_pcids[PCPU_GET(cpuid)].pm_pcid);
+ }
+ }
atomic_add_int(&smp_tlb_wait, 1);
}
void
-invlpg_pcid_handler(void)
+invlpg_handler(void)
{
- uint64_t cr3;
#ifdef COUNT_XINVLTLB_HITS
xhits_pg[PCPU_GET(cpuid)]++;
#endif /* COUNT_XINVLTLB_HITS */
@@ -647,45 +582,15 @@ invlpg_pcid_handler(void)
(*ipi_invlpg_counts[PCPU_GET(cpuid)])++;
#endif /* COUNT_IPIS */
- if (smp_tlb_invpcid.pcid == (uint64_t)-1) {
- invltlb_globpcid();
- } else if (smp_tlb_invpcid.pcid == 0) {
- invlpg(smp_tlb_invpcid.addr);
- } else if (invpcid_works) {
- invpcid(&smp_tlb_invpcid, INVPCID_ADDR);
- } else {
- /*
- * PCID supported, but INVPCID is not.
- * Temporarily switch to the target address
- * space and do INVLPG.
- */
- cr3 = rcr3();
- if (cr3 != pcid_cr3)
- load_cr3(pcid_cr3 | CR3_PCID_SAVE);
- invlpg(smp_tlb_invpcid.addr);
- load_cr3(cr3 | CR3_PCID_SAVE);
- }
-
+ invlpg(smp_tlb_addr1);
atomic_add_int(&smp_tlb_wait, 1);
}
-static inline void
-invlpg_range(vm_offset_t start, vm_offset_t end)
-{
-
- do {
- invlpg(start);
- start += PAGE_SIZE;
- } while (start < end);
-}
-
void
invlrng_handler(void)
{
- struct invpcid_descr d;
vm_offset_t addr;
- uint64_t cr3;
- u_int cpuid;
+
#ifdef COUNT_XINVLTLB_HITS
xhits_rng[PCPU_GET(cpuid)]++;
#endif /* COUNT_XINVLTLB_HITS */
@@ -693,38 +598,11 @@ invlrng_handler(void)
(*ipi_invlrng_counts[PCPU_GET(cpuid)])++;
#endif /* COUNT_IPIS */
- addr = smp_tlb_invpcid.addr;
- if (pmap_pcid_enabled) {
- if (smp_tlb_invpcid.pcid == 0) {
- /*
- * kernel pmap - use invlpg to invalidate
- * global mapping.
- */
- invlpg_range(addr, smp_tlb_addr2);
- } else if (smp_tlb_invpcid.pcid == (uint64_t)-1) {
- invltlb_globpcid();
- if (smp_tlb_pmap != NULL) {
- cpuid = PCPU_GET(cpuid);
- if (!CPU_ISSET(cpuid, &smp_tlb_pmap->pm_active))
- CPU_CLR_ATOMIC(cpuid,
- &smp_tlb_pmap->pm_save);
- }
- } else if (invpcid_works) {
- d = smp_tlb_invpcid;
- do {
- invpcid(&d, INVPCID_ADDR);
- d.addr += PAGE_SIZE;
- } while (d.addr <= smp_tlb_addr2);
- } else {
- cr3 = rcr3();
- if (cr3 != pcid_cr3)
- load_cr3(pcid_cr3 | CR3_PCID_SAVE);
- invlpg_range(addr, smp_tlb_addr2);
- load_cr3(cr3 | CR3_PCID_SAVE);
- }
- } else {
- invlpg_range(addr, smp_tlb_addr2);
- }
+ addr = smp_tlb_addr1;
+ do {
+ invlpg(addr);
+ addr += PAGE_SIZE;
+ } while (addr < smp_tlb_addr2);
atomic_add_int(&smp_tlb_wait, 1);
}
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index dc823fa..e18676a 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -273,6 +273,8 @@ pmap_modified_bit(pmap_t pmap)
return (mask);
}
+extern struct pcpu __pcpu[];
+
#if !defined(DIAGNOSTIC)
#ifdef __GNUC_GNU_INLINE__
#define PMAP_INLINE __attribute__((__gnu_inline__)) inline
@@ -379,8 +381,6 @@ caddr_t CADDR1 = 0;
static int pmap_flags = PMAP_PDE_SUPERPAGE; /* flags for x86 pmaps */
-static struct unrhdr pcid_unr;
-static struct mtx pcid_mtx;
int pmap_pcid_enabled = 0;
SYSCTL_INT(_vm_pmap, OID_AUTO, pcid_enabled, CTLFLAG_RDTUN | CTLFLAG_NOFETCH,
&pmap_pcid_enabled, 0, "Is TLB Context ID enabled ?");
@@ -827,6 +827,7 @@ pmap_bootstrap(vm_paddr_t *firstaddr)
{
vm_offset_t va;
pt_entry_t *pte;
+ int i;
/*
* Create an initial set of page tables to run the kernel in.
@@ -861,7 +862,6 @@ pmap_bootstrap(vm_paddr_t *firstaddr)
kernel_pmap->pm_pml4 = (pdp_entry_t *)PHYS_TO_DMAP(KPML4phys);
kernel_pmap->pm_cr3 = KPML4phys;
CPU_FILL(&kernel_pmap->pm_active); /* don't allow deactivation */
- CPU_FILL(&kernel_pmap->pm_save); /* always superset of pm_active */
TAILQ_INIT(&kernel_pmap->pm_pvchunk);
kernel_pmap->pm_flags = pmap_flags;
@@ -895,18 +895,28 @@ pmap_bootstrap(vm_paddr_t *firstaddr)
/* Initialize TLB Context Id. */
TUNABLE_INT_FETCH("vm.pmap.pcid_enabled", &pmap_pcid_enabled);
if ((cpu_feature2 & CPUID2_PCID) != 0 && pmap_pcid_enabled) {
- load_cr4(rcr4() | CR4_PCIDE);
- mtx_init(&pcid_mtx, "pcid", NULL, MTX_DEF);
- init_unrhdr(&pcid_unr, 1, (1 << 12) - 1, &pcid_mtx);
/* Check for INVPCID support */
invpcid_works = (cpu_stdext_feature & CPUID_STDEXT_INVPCID)
!= 0;
- kernel_pmap->pm_pcid = 0;
-#ifndef SMP
+ for (i = 0; i < MAXCPU; i++) {
+ kernel_pmap->pm_pcids[i].pm_pcid = PMAP_PCID_KERN;
+ kernel_pmap->pm_pcids[i].pm_gen = 1;
+ }
+ __pcpu[0].pc_pcid_next = PMAP_PCID_KERN + 1;
+ __pcpu[0].pc_pcid_gen = 1;
+ /*
+ * pcpu area for APs is zeroed during AP startup.
+ * pc_pcid_next and pc_pcid_gen are initialized by AP
+ * during pcpu setup.
+ */
+#ifdef SMP
+ load_cr4(rcr4() | CR4_PCIDE);
+#else
pmap_pcid_enabled = 0;
#endif
- } else
+ } else {
pmap_pcid_enabled = 0;
+ }
}
/*
@@ -1277,28 +1287,6 @@ pmap_update_pde_invalidate(pmap_t pmap, vm_offset_t va, pd_entry_t newpde)
}
#ifdef SMP
-static void
-pmap_invalidate_page_pcid(pmap_t pmap, vm_offset_t va)
-{
- struct invpcid_descr d;
- uint64_t cr3;
-
- if (invpcid_works) {
- d.pcid = pmap->pm_pcid;
- d.pad = 0;
- d.addr = va;
- invpcid(&d, INVPCID_ADDR);
- return;
- }
-
- cr3 = rcr3();
- critical_enter();
- load_cr3(pmap->pm_cr3 | CR3_PCID_SAVE);
- invlpg(va);
- load_cr3(cr3 | CR3_PCID_SAVE);
- critical_exit();
-}
-
/*
* For SMP, these functions have to use the IPI mechanism for coherence.
*
@@ -1361,8 +1349,8 @@ pmap_invalidate_ept(pmap_t pmap)
void
pmap_invalidate_page(pmap_t pmap, vm_offset_t va)
{
- cpuset_t other_cpus;
- u_int cpuid;
+ cpuset_t *mask;
+ u_int cpuid, i;
if (pmap_type_guest(pmap)) {
pmap_invalidate_ept(pmap);
@@ -1373,74 +1361,33 @@ pmap_invalidate_page(pmap_t pmap, vm_offset_t va)
("pmap_invalidate_page: invalid type %d", pmap->pm_type));
sched_pin();
- if (pmap == kernel_pmap || !CPU_CMP(&pmap->pm_active, &all_cpus)) {
- if (!pmap_pcid_enabled) {
- invlpg(va);
- } else {
- if (pmap->pm_pcid != -1 && pmap->pm_pcid != 0) {
- if (pmap == PCPU_GET(curpmap))
- invlpg(va);
- else
- pmap_invalidate_page_pcid(pmap, va);
- } else {
- invltlb_globpcid();
- }
- }
- smp_invlpg(pmap, va);
+ if (pmap == kernel_pmap) {
+ invlpg(va);
+ mask = &all_cpus;
} else {
cpuid = PCPU_GET(cpuid);
- other_cpus = all_cpus;
- CPU_CLR(cpuid, &other_cpus);
- if (CPU_ISSET(cpuid, &pmap->pm_active))
+ if (pmap == PCPU_GET(curpmap))
invlpg(va);
- else if (pmap_pcid_enabled) {
- if (pmap->pm_pcid != -1 && pmap->pm_pcid != 0)
- pmap_invalidate_page_pcid(pmap, va);
- else
- invltlb_globpcid();
+ else if (pmap_pcid_enabled)
+ pmap->pm_pcids[cpuid].pm_gen = 0;
+ if (pmap_pcid_enabled) {
+ CPU_FOREACH(i) {
+ if (cpuid != i)
+ pmap->pm_pcids[i].pm_gen = 0;
+ }
}
- if (pmap_pcid_enabled)
- CPU_AND(&other_cpus, &pmap->pm_save);
- else
- CPU_AND(&other_cpus, &pmap->pm_active);
- if (!CPU_EMPTY(&other_cpus))
- smp_masked_invlpg(other_cpus, pmap, va);
+ mask = &pmap->pm_active;
}
+ smp_masked_invlpg(*mask, va);
sched_unpin();
}
-static void
-pmap_invalidate_range_pcid(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
-{
- struct invpcid_descr d;
- uint64_t cr3;
- vm_offset_t addr;
-
- if (invpcid_works) {
- d.pcid = pmap->pm_pcid;
- d.pad = 0;
- for (addr = sva; addr < eva; addr += PAGE_SIZE) {
- d.addr = addr;
- invpcid(&d, INVPCID_ADDR);
- }
- return;
- }
-
- cr3 = rcr3();
- critical_enter();
- load_cr3(pmap->pm_cr3 | CR3_PCID_SAVE);
- for (addr = sva; addr < eva; addr += PAGE_SIZE)
- invlpg(addr);
- load_cr3(cr3 | CR3_PCID_SAVE);
- critical_exit();
-}
-
void
pmap_invalidate_range(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
{
- cpuset_t other_cpus;
+ cpuset_t *mask;
vm_offset_t addr;
- u_int cpuid;
+ u_int cpuid, i;
if (pmap_type_guest(pmap)) {
pmap_invalidate_ept(pmap);
@@ -1451,55 +1398,36 @@ pmap_invalidate_range(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
("pmap_invalidate_range: invalid type %d", pmap->pm_type));
sched_pin();
- if (pmap == kernel_pmap || !CPU_CMP(&pmap->pm_active, &all_cpus)) {
- if (!pmap_pcid_enabled) {
- for (addr = sva; addr < eva; addr += PAGE_SIZE)
- invlpg(addr);
- } else {
- if (pmap->pm_pcid != -1 && pmap->pm_pcid != 0) {
- if (pmap == PCPU_GET(curpmap)) {
- for (addr = sva; addr < eva;
- addr += PAGE_SIZE)
- invlpg(addr);
- } else {
- pmap_invalidate_range_pcid(pmap,
- sva, eva);
- }
- } else {
- invltlb_globpcid();
- }
- }
- smp_invlpg_range(pmap, sva, eva);
+ cpuid = PCPU_GET(cpuid);
+ if (pmap == kernel_pmap) {
+ for (addr = sva; addr < eva; addr += PAGE_SIZE)
+ invlpg(addr);
+ mask = &all_cpus;
} else {
- cpuid = PCPU_GET(cpuid);
- other_cpus = all_cpus;
- CPU_CLR(cpuid, &other_cpus);
- if (CPU_ISSET(cpuid, &pmap->pm_active)) {
+ if (pmap == PCPU_GET(curpmap)) {
for (addr = sva; addr < eva; addr += PAGE_SIZE)
invlpg(addr);
} else if (pmap_pcid_enabled) {
- if (pmap->pm_pcid != -1 && pmap->pm_pcid != 0)
- pmap_invalidate_range_pcid(pmap, sva, eva);
- else
- invltlb_globpcid();
+ pmap->pm_pcids[cpuid].pm_gen = 0;
}
- if (pmap_pcid_enabled)
- CPU_AND(&other_cpus, &pmap->pm_save);
- else
- CPU_AND(&other_cpus, &pmap->pm_active);
- if (!CPU_EMPTY(&other_cpus))
- smp_masked_invlpg_range(other_cpus, pmap, sva, eva);
+ if (pmap_pcid_enabled) {
+ CPU_FOREACH(i) {
+ if (cpuid != i)
+ pmap->pm_pcids[i].pm_gen = 0;
+ }
+ }
+ mask = &pmap->pm_active;
}
+ smp_masked_invlpg_range(*mask, sva, eva);
sched_unpin();
}
void
pmap_invalidate_all(pmap_t pmap)
{
- cpuset_t other_cpus;
+ cpuset_t *mask;
struct invpcid_descr d;
- uint64_t cr3;
- u_int cpuid;
+ u_int cpuid, i;
if (pmap_type_guest(pmap)) {
pmap_invalidate_ept(pmap);
@@ -1510,60 +1438,42 @@ pmap_invalidate_all(pmap_t pmap)
("pmap_invalidate_all: invalid type %d", pmap->pm_type));
sched_pin();
- cpuid = PCPU_GET(cpuid);
- if (pmap == kernel_pmap ||
- (pmap_pcid_enabled && !CPU_CMP(&pmap->pm_save, &all_cpus)) ||
- !CPU_CMP(&pmap->pm_active, &all_cpus)) {
- if (invpcid_works) {
+ if (pmap == kernel_pmap) {
+ if (pmap_pcid_enabled && invpcid_works) {
bzero(&d, sizeof(d));
invpcid(&d, INVPCID_CTXGLOB);
} else {
invltlb_globpcid();
}
- if (!CPU_ISSET(cpuid, &pmap->pm_active))
- CPU_CLR_ATOMIC(cpuid, &pmap->pm_save);
- smp_invltlb(pmap);
+ mask = &all_cpus;
} else {
- other_cpus = all_cpus;
- CPU_CLR(cpuid, &other_cpus);
-
- /*
- * This logic is duplicated in the Xinvltlb shootdown
- * IPI handler.
- */
- if (pmap_pcid_enabled) {
- if (pmap->pm_pcid != -1 && pmap->pm_pcid != 0) {
+ cpuid = PCPU_GET(cpuid);
+ if (pmap == PCPU_GET(curpmap)) {
+ if (pmap_pcid_enabled) {
if (invpcid_works) {
- d.pcid = pmap->pm_pcid;
+ d.pcid = pmap->pm_pcids[cpuid].pm_pcid;
d.pad = 0;
d.addr = 0;
invpcid(&d, INVPCID_CTX);
} else {
- cr3 = rcr3();
- critical_enter();
-
- /*
- * Bit 63 is clear, pcid TLB
- * entries are invalidated.
- */
- load_cr3(pmap->pm_cr3);
- load_cr3(cr3 | CR3_PCID_SAVE);
- critical_exit();
+ load_cr3(pmap->pm_cr3 | pmap->pm_pcids
+ [PCPU_GET(cpuid)].pm_pcid);
}
} else {
- invltlb_globpcid();
+ invltlb();
}
- } else if (CPU_ISSET(cpuid, &pmap->pm_active))
- invltlb();
- if (!CPU_ISSET(cpuid, &pmap->pm_active))
- CPU_CLR_ATOMIC(cpuid, &pmap->pm_save);
- if (pmap_pcid_enabled)
- CPU_AND(&other_cpus, &pmap->pm_save);
- else
- CPU_AND(&other_cpus, &pmap->pm_active);
- if (!CPU_EMPTY(&other_cpus))
- smp_masked_invltlb(other_cpus, pmap);
+ } else if (pmap_pcid_enabled) {
+ pmap->pm_pcids[cpuid].pm_gen = 0;
+ }
+ if (pmap_pcid_enabled) {
+ CPU_FOREACH(i) {
+ if (cpuid != i)
+ pmap->pm_pcids[i].pm_gen = 0;
+ }
+ }
+ mask = &pmap->pm_active;
}
+ smp_masked_invltlb(*mask, pmap);
sched_unpin();
}
@@ -1627,7 +1537,6 @@ pmap_update_pde(pmap_t pmap, vm_offset_t va, pd_entry_t *pde, pd_entry_t newpde)
active = all_cpus;
else {
active = pmap->pm_active;
- CPU_AND_ATOMIC(&pmap->pm_save, &active);
}
if (CPU_OVERLAP(&active, &other_cpus)) {
act.store = cpuid;
@@ -2205,11 +2114,9 @@ pmap_pinit0(pmap_t pmap)
pmap->pm_cr3 = KPML4phys;
pmap->pm_root.rt_root = 0;
CPU_ZERO(&pmap->pm_active);
- CPU_ZERO(&pmap->pm_save);
PCPU_SET(curpmap, pmap);
TAILQ_INIT(&pmap->pm_pvchunk);
bzero(&pmap->pm_stats, sizeof pmap->pm_stats);
- pmap->pm_pcid = pmap_pcid_enabled ? 0 : -1;
pmap->pm_flags = pmap_flags;
}
@@ -2233,7 +2140,10 @@ pmap_pinit_type(pmap_t pmap, enum pmap_type pm_type, int flags)
pml4phys = VM_PAGE_TO_PHYS(pml4pg);
pmap->pm_pml4 = (pml4_entry_t *)PHYS_TO_DMAP(pml4phys);
- pmap->pm_pcid = -1;
+ CPU_FOREACH(i) {
+ pmap->pm_pcids[i].pm_pcid = PMAP_PCID_NONE;
+ pmap->pm_pcids[i].pm_gen = 0;
+ }
pmap->pm_cr3 = ~0; /* initialize to an invalid value */
if ((pml4pg->flags & PG_ZERO) == 0)
@@ -2260,12 +2170,6 @@ pmap_pinit_type(pmap_t pmap, enum pmap_type pm_type, int flags)
/* install self-referential address mapping entry(s) */
pmap->pm_pml4[PML4PML4I] = VM_PAGE_TO_PHYS(pml4pg) |
X86_PG_V | X86_PG_RW | X86_PG_A | X86_PG_M;
-
- if (pmap_pcid_enabled) {
- pmap->pm_pcid = alloc_unr(&pcid_unr);
- if (pmap->pm_pcid != -1)
- pmap->pm_cr3 |= pmap->pm_pcid;
- }
}
pmap->pm_root.rt_root = 0;
@@ -2274,7 +2178,6 @@ pmap_pinit_type(pmap_t pmap, enum pmap_type pm_type, int flags)
bzero(&pmap->pm_stats, sizeof pmap->pm_stats);
pmap->pm_flags = flags;
pmap->pm_eptgen = 0;
- CPU_ZERO(&pmap->pm_save);
return (1);
}
@@ -2535,14 +2438,6 @@ pmap_release(pmap_t pmap)
KASSERT(CPU_EMPTY(&pmap->pm_active),
("releasing active pmap %p", pmap));
- if (pmap_pcid_enabled) {
- /*
- * Invalidate any left TLB entries, to allow the reuse
- * of the pcid.
- */
- pmap_invalidate_all(pmap);
- }
-
m = PHYS_TO_VM_PAGE(DMAP_TO_PHYS((vm_offset_t)pmap->pm_pml4));
for (i = 0; i < NKPML4E; i++) /* KVA */
@@ -2554,8 +2449,6 @@ pmap_release(pmap_t pmap)
m->wire_count--;
atomic_subtract_int(&vm_cnt.v_wire_count, 1);
vm_page_free_zero(m);
- if (pmap->pm_pcid != -1)
- free_unr(&pcid_unr, pmap->pm_pcid);
}
static int
@@ -6657,28 +6550,84 @@ retry:
return (val);
}
+static uint64_t
+pmap_pcid_alloc(pmap_t pmap, u_int cpuid)
+{
+ uint32_t gen, new_gen, pcid_next;
+
+ CRITICAL_ASSERT(curthread);
+ gen = PCPU_GET(pcid_gen);
+ if (pmap->pm_pcids[cpuid].pm_pcid == PMAP_PCID_KERN ||
+ pmap->pm_pcids[cpuid].pm_gen == gen)
+ return (CR3_PCID_SAVE);
+ pcid_next = PCPU_GET(pcid_next);
+ KASSERT(pcid_next <= PMAP_PCID_OVERMAX, ("cpu %d pcid_next %#x",
+ cpuid, pcid_next));
+ if (pcid_next == PMAP_PCID_OVERMAX) {
+ new_gen = gen + 1;
+ if (new_gen == 0)
+ new_gen = 1;
+ PCPU_SET(pcid_gen, new_gen);
+ pcid_next = PMAP_PCID_KERN + 1;
+ } else {
+ new_gen = gen;
+ }
+ pmap->pm_pcids[cpuid].pm_pcid = pcid_next;
+ pmap->pm_pcids[cpuid].pm_gen = new_gen;
+ PCPU_SET(pcid_next, pcid_next + 1);
+ return (0);
+}
+
void
-pmap_activate(struct thread *td)
+pmap_activate_sw(struct thread *td)
{
- pmap_t pmap, oldpmap;
- u_int cpuid;
+ pmap_t oldpmap, pmap;
+ uint64_t cached, cr3;
+ u_int cpuid;
- critical_enter();
- pmap = vmspace_pmap(td->td_proc->p_vmspace);
oldpmap = PCPU_GET(curpmap);
+ pmap = vmspace_pmap(td->td_proc->p_vmspace);
+ if (oldpmap == pmap)
+ return;
cpuid = PCPU_GET(cpuid);
#ifdef SMP
- CPU_CLR_ATOMIC(cpuid, &oldpmap->pm_active);
CPU_SET_ATOMIC(cpuid, &pmap->pm_active);
- CPU_SET_ATOMIC(cpuid, &pmap->pm_save);
#else
- CPU_CLR(cpuid, &oldpmap->pm_active);
CPU_SET(cpuid, &pmap->pm_active);
- CPU_SET(cpuid, &pmap->pm_save);
#endif
- td->td_pcb->pcb_cr3 = pmap->pm_cr3;
- load_cr3(pmap->pm_cr3);
+ cr3 = rcr3();
+ if (pmap_pcid_enabled) {
+ cached = pmap_pcid_alloc(pmap, cpuid);
+ KASSERT(pmap->pm_pcids[cpuid].pm_pcid >= 0 &&
+ pmap->pm_pcids[cpuid].pm_pcid < PMAP_PCID_OVERMAX,
+ ("pmap %p cpu %d pcid %#x", pmap, cpuid,
+ pmap->pm_pcids[cpuid].pm_pcid));
+ KASSERT(pmap != PMAP_PCID_KERN || pmap == kernel_pmap,
+ ("non-kernel pmap %p cpu %d pcid %#x", pmap, cpuid,
+ pmap->pm_pcids[cpuid].pm_pcid));
+ if (!cached || (cr3 & ~CR3_PCID_MASK) != pmap->pm_cr3) {
+ load_cr3(pmap->pm_cr3 | pmap->pm_pcids[cpuid].pm_pcid |
+ cached);
+ if (cached)
+ PCPU_INC(pm_save_cnt);
+ }
+ } else if (cr3 != pmap->pm_cr3) {
+ load_cr3(pmap->pm_cr3);
+ }
PCPU_SET(curpmap, pmap);
+#ifdef SMP
+ CPU_CLR_ATOMIC(cpuid, &oldpmap->pm_active);
+#else
+ CPU_CLR(cpuid, &oldpmap->pm_active);
+#endif
+}
+
+void
+pmap_activate(struct thread *td)
+{
+
+ critical_enter();
+ pmap_activate_sw(td);
critical_exit();
}
diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c
index 26ac7ab..0d03ed6 100644
--- a/sys/amd64/amd64/vm_machdep.c
+++ b/sys/amd64/amd64/vm_machdep.c
@@ -219,7 +219,6 @@ cpu_fork(td1, p2, td2, flags)
* return address on stack. These are the kernel mode register values.
*/
pmap2 = vmspace_pmap(p2->p_vmspace);
- pcb2->pcb_cr3 = pmap2->pm_cr3;
pcb2->pcb_r12 = (register_t)fork_return; /* fork_trampoline argument */
pcb2->pcb_rbp = 0;
pcb2->pcb_rsp = (register_t)td2->td_frame - sizeof(void *);
@@ -477,7 +476,6 @@ cpu_set_upcall(struct thread *td, struct thread *td0)
pcb2->pcb_rip = (register_t)fork_trampoline;
/*
* If we didn't copy the pcb, we'd need to do the following registers:
- * pcb2->pcb_cr3: cloned above.
* pcb2->pcb_dr*: cloned above.
* pcb2->pcb_savefpu: cloned above.
* pcb2->pcb_onfault: cloned above (always NULL here?).
diff --git a/sys/amd64/include/cpufunc.h b/sys/amd64/include/cpufunc.h
index 7ea4bcf..c0c5b0a 100644
--- a/sys/amd64/include/cpufunc.h
+++ b/sys/amd64/include/cpufunc.h
@@ -540,9 +540,8 @@ static __inline void
invpcid(struct invpcid_descr *d, int type)
{
- /* invpcid (%rdx),%rax */
- __asm __volatile(".byte 0x66,0x0f,0x38,0x82,0x02"
- : : "d" (d), "a" ((u_long)type) : "memory");
+ __asm __volatile("invpcid (%0),%1"
+ : : "r" (d), "r" ((u_long)type) : "memory");
}
static __inline u_short
diff --git a/sys/amd64/include/md_var.h b/sys/amd64/include/md_var.h
index 9083421..0813e5f 100644
--- a/sys/amd64/include/md_var.h
+++ b/sys/amd64/include/md_var.h
@@ -91,6 +91,7 @@ struct dumperinfo;
void *alloc_fpusave(int flags);
void amd64_syscall(struct thread *td, int traced);
void busdma_swi(void);
+bool cpu_mwait_usable(void);
void cpu_probe_amdc1e(void);
void cpu_setregs(void);
void doreti_iret(void) __asm(__STRING(doreti_iret));
diff --git a/sys/amd64/include/pcpu.h b/sys/amd64/include/pcpu.h
index fe898e9..91e8fb2 100644
--- a/sys/amd64/include/pcpu.h
+++ b/sys/amd64/include/pcpu.h
@@ -63,7 +63,9 @@
uint64_t pc_dbreg[16]; /* ddb debugging regs */ \
int pc_dbreg_cmd; /* ddb debugging reg cmd */ \
u_int pc_vcpu_id; /* Xen vCPU ID */ \
- char __pad[157] /* be divisor of PAGE_SIZE \
+ uint32_t pc_pcid_next; \
+ uint32_t pc_pcid_gen; \
+ char __pad[149] /* be divisor of PAGE_SIZE \
after cache alignment */
#define PC_DBREG_CMD_NONE 0
diff --git a/sys/amd64/include/pmap.h b/sys/amd64/include/pmap.h
index 868db7d..39df87a 100644
--- a/sys/amd64/include/pmap.h
+++ b/sys/amd64/include/pmap.h
@@ -219,6 +219,10 @@
#define ISA_HOLE_START 0xa0000
#define ISA_HOLE_LENGTH (0x100000-ISA_HOLE_START)
+#define PMAP_PCID_NONE 0xffffffff
+#define PMAP_PCID_KERN 0
+#define PMAP_PCID_OVERMAX 0x1000
+
#ifndef LOCORE
#include <sys/queue.h>
@@ -292,6 +296,11 @@ enum pmap_type {
PT_RVI, /* AMD's nested page tables */
};
+struct pmap_pcids {
+ uint32_t pm_pcid;
+ uint32_t pm_gen;
+};
+
/*
* The kernel virtual address (KVA) of the level 4 page table page is always
* within the direct map (DMAP) region.
@@ -302,13 +311,12 @@ struct pmap {
uint64_t pm_cr3;
TAILQ_HEAD(,pv_chunk) pm_pvchunk; /* list of mappings in pmap */
cpuset_t pm_active; /* active on cpus */
- cpuset_t pm_save; /* Context valid on cpus mask */
- int pm_pcid; /* context id */
enum pmap_type pm_type; /* regular or nested tables */
struct pmap_statistics pm_stats; /* pmap statistics */
struct vm_radix pm_root; /* spare page table pages */
long pm_eptgen; /* EPT pmap generation id */
int pm_flags;
+ struct pmap_pcids pm_pcids[MAXCPU];
};
/* flags */
@@ -375,6 +383,9 @@ extern vm_paddr_t dmaplimit;
#define pmap_page_is_write_mapped(m) (((m)->aflags & PGA_WRITEABLE) != 0)
#define pmap_unmapbios(va, sz) pmap_unmapdev((va), (sz))
+struct thread;
+
+void pmap_activate_sw(struct thread *);
void pmap_bootstrap(vm_paddr_t *);
int pmap_change_attr(vm_offset_t, vm_size_t, int);
void pmap_demote_DMAP(vm_paddr_t base, vm_size_t len, boolean_t invalidate);
diff --git a/sys/amd64/include/smp.h b/sys/amd64/include/smp.h
index 034a693..4fd6aac 100644
--- a/sys/amd64/include/smp.h
+++ b/sys/amd64/include/smp.h
@@ -46,6 +46,7 @@ extern struct mtx ap_boot_mtx;
extern int cpu_logical;
extern int cpu_cores;
extern int pmap_pcid_enabled;
+extern int invpcid_works;
extern u_int xhits_gbl[];
extern u_int xhits_pg[];
extern u_int xhits_rng[];
@@ -53,10 +54,6 @@ extern u_int ipi_global;
extern u_int ipi_page;
extern u_int ipi_range;
extern u_int ipi_range_size;
-extern u_int ipi_masked_global;
-extern u_int ipi_masked_page;
-extern u_int ipi_masked_range;
-extern u_int ipi_masked_range_size;
extern volatile int smp_tlb_wait;
@@ -78,9 +75,9 @@ extern u_long *ipi_rendezvous_counts[MAXCPU];
/* IPI handlers */
inthand_t
- IDTVEC(invltlb_pcid), /* TLB shootdowns - global, pcid enabled */
IDTVEC(invltlb), /* TLB shootdowns - global */
- IDTVEC(invlpg_pcid), /* TLB shootdowns - 1 page, pcid enabled */
+ IDTVEC(invltlb_pcid), /* TLB shootdowns - global, pcid */
+ IDTVEC(invltlb_invpcid),/* TLB shootdowns - global, invpcid */
IDTVEC(invlpg), /* TLB shootdowns - 1 page */
IDTVEC(invlrng), /* TLB shootdowns - page range */
IDTVEC(invlcache), /* Write back and invalidate cache */
@@ -100,8 +97,8 @@ void cpususpend_handler(void);
void init_secondary_tail(void);
void invltlb_handler(void);
void invltlb_pcid_handler(void);
+void invltlb_invpcid_handler(void);
void invlpg_handler(void);
-void invlpg_pcid_handler(void);
void invlrng_handler(void);
void invlcache_handler(void);
void init_secondary(void);
@@ -114,13 +111,9 @@ void ipi_selected(cpuset_t cpus, u_int ipi);
u_int mp_bootaddress(u_int);
void set_interrupt_apic_ids(void);
void smp_cache_flush(void);
-void smp_invlpg(struct pmap *pmap, vm_offset_t addr);
-void smp_masked_invlpg(cpuset_t mask, struct pmap *pmap, vm_offset_t addr);
-void smp_invlpg_range(struct pmap *pmap, vm_offset_t startva,
+void smp_masked_invlpg(cpuset_t mask, vm_offset_t addr);
+void smp_masked_invlpg_range(cpuset_t mask, vm_offset_t startva,
vm_offset_t endva);
-void smp_masked_invlpg_range(cpuset_t mask, struct pmap *pmap,
- vm_offset_t startva, vm_offset_t endva);
-void smp_invltlb(struct pmap *pmap);
void smp_masked_invltlb(cpuset_t mask, struct pmap *pmap);
int native_start_all_aps(void);
void mem_range_AP_init(void);
diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h
index 7c617be..d3798bc 100644
--- a/sys/amd64/include/vmm.h
+++ b/sys/amd64/include/vmm.h
@@ -276,7 +276,13 @@ vcpu_is_running(struct vm *vm, int vcpu, int *hostcpu)
static int __inline
vcpu_should_yield(struct vm *vm, int vcpu)
{
- return (curthread->td_flags & (TDF_ASTPENDING | TDF_NEEDRESCHED));
+
+ if (curthread->td_flags & (TDF_ASTPENDING | TDF_NEEDRESCHED))
+ return (1);
+ else if (curthread->td_owepreempt)
+ return (1);
+ else
+ return (0);
}
#endif
@@ -345,9 +351,10 @@ struct vm_copyinfo {
* at 'gla' and 'len' bytes long. The 'prot' should be set to PROT_READ for
* a copyin or PROT_WRITE for a copyout.
*
- * Returns 0 on success.
- * Returns 1 if an exception was injected into the guest.
- * Returns -1 otherwise.
+ * retval is_fault Intepretation
+ * 0 0 Success
+ * 0 1 An exception was injected into the guest
+ * EFAULT N/A Unrecoverable error
*
* The 'copyinfo[]' can be passed to 'vm_copyin()' or 'vm_copyout()' only if
* the return value is 0. The 'copyinfo[]' resources should be freed by calling
@@ -355,7 +362,7 @@ struct vm_copyinfo {
*/
int vm_copy_setup(struct vm *vm, int vcpuid, struct vm_guest_paging *paging,
uint64_t gla, size_t len, int prot, struct vm_copyinfo *copyinfo,
- int num_copyinfo);
+ int num_copyinfo, int *is_fault);
void vm_copy_teardown(struct vm *vm, int vcpuid, struct vm_copyinfo *copyinfo,
int num_copyinfo);
void vm_copyin(struct vm *vm, int vcpuid, struct vm_copyinfo *copyinfo,
diff --git a/sys/amd64/include/vmm_instruction_emul.h b/sys/amd64/include/vmm_instruction_emul.h
index 651b3b3..5e7127f 100644
--- a/sys/amd64/include/vmm_instruction_emul.h
+++ b/sys/amd64/include/vmm_instruction_emul.h
@@ -81,17 +81,19 @@ int vie_calculate_gla(enum vm_cpu_mode cpu_mode, enum vm_reg_name seg,
*/
int vmm_fetch_instruction(struct vm *vm, int cpuid,
struct vm_guest_paging *guest_paging,
- uint64_t rip, int inst_length, struct vie *vie);
+ uint64_t rip, int inst_length, struct vie *vie,
+ int *is_fault);
/*
* Translate the guest linear address 'gla' to a guest physical address.
*
- * Returns 0 on success and '*gpa' contains the result of the translation.
- * Returns 1 if an exception was injected into the guest.
- * Returns -1 otherwise.
+ * retval is_fault Interpretation
+ * 0 0 'gpa' contains result of the translation
+ * 0 1 An exception was injected into the guest
+ * EFAULT N/A An unrecoverable hypervisor error occurred
*/
int vm_gla2gpa(struct vm *vm, int vcpuid, struct vm_guest_paging *paging,
- uint64_t gla, int prot, uint64_t *gpa);
+ uint64_t gla, int prot, uint64_t *gpa, int *is_fault);
void vie_init(struct vie *vie, const char *inst_bytes, int inst_length);
diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c
index bca9b98..51c63f5 100644
--- a/sys/amd64/vmm/vmm.c
+++ b/sys/amd64/vmm/vmm.c
@@ -1256,7 +1256,7 @@ vm_handle_inst_emul(struct vm *vm, int vcpuid, bool *retu)
mem_region_read_t mread;
mem_region_write_t mwrite;
enum vm_cpu_mode cpu_mode;
- int cs_d, error, length;
+ int cs_d, error, fault, length;
vcpu = &vm->vcpu[vcpuid];
vme = &vcpu->exitinfo;
@@ -1279,19 +1279,15 @@ vm_handle_inst_emul(struct vm *vm, int vcpuid, bool *retu)
*/
length = vme->inst_length ? vme->inst_length : VIE_INST_SIZE;
error = vmm_fetch_instruction(vm, vcpuid, paging, vme->rip +
- cs_base, length, vie);
+ cs_base, length, vie, &fault);
} else {
/*
* The instruction bytes have already been copied into 'vie'
*/
- error = 0;
+ error = fault = 0;
}
- if (error == 1)
- return (0); /* Resume guest to handle page fault */
- else if (error == -1)
- return (EFAULT);
- else if (error != 0)
- panic("%s: vmm_fetch_instruction error %d", __func__, error);
+ if (error || fault)
+ return (error);
if (vmm_decode_instruction(vm, vcpuid, gla, cpu_mode, cs_d, vie) != 0) {
VCPU_CTR1(vm, vcpuid, "Error decoding instruction at %#lx",
@@ -2323,7 +2319,7 @@ vm_copy_teardown(struct vm *vm, int vcpuid, struct vm_copyinfo *copyinfo,
int
vm_copy_setup(struct vm *vm, int vcpuid, struct vm_guest_paging *paging,
uint64_t gla, size_t len, int prot, struct vm_copyinfo *copyinfo,
- int num_copyinfo)
+ int num_copyinfo, int *fault)
{
int error, idx, nused;
size_t n, off, remaining;
@@ -2336,8 +2332,8 @@ vm_copy_setup(struct vm *vm, int vcpuid, struct vm_guest_paging *paging,
remaining = len;
while (remaining > 0) {
KASSERT(nused < num_copyinfo, ("insufficient vm_copyinfo"));
- error = vm_gla2gpa(vm, vcpuid, paging, gla, prot, &gpa);
- if (error)
+ error = vm_gla2gpa(vm, vcpuid, paging, gla, prot, &gpa, fault);
+ if (error || *fault)
return (error);
off = gpa & PAGE_MASK;
n = min(remaining, PAGE_SIZE - off);
@@ -2359,8 +2355,9 @@ vm_copy_setup(struct vm *vm, int vcpuid, struct vm_guest_paging *paging,
if (idx != nused) {
vm_copy_teardown(vm, vcpuid, copyinfo, num_copyinfo);
- return (-1);
+ return (EFAULT);
} else {
+ *fault = 0;
return (0);
}
}
diff --git a/sys/amd64/vmm/vmm_dev.c b/sys/amd64/vmm/vmm_dev.c
index 5be99cb..e3e140a 100644
--- a/sys/amd64/vmm/vmm_dev.c
+++ b/sys/amd64/vmm/vmm_dev.c
@@ -441,19 +441,9 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
CTASSERT(PROT_EXEC == VM_PROT_EXECUTE);
gg = (struct vm_gla2gpa *)data;
error = vm_gla2gpa(sc->vm, gg->vcpuid, &gg->paging, gg->gla,
- gg->prot, &gg->gpa);
- KASSERT(error == 0 || error == 1 || error == -1,
+ gg->prot, &gg->gpa, &gg->fault);
+ KASSERT(error == 0 || error == EFAULT,
("%s: vm_gla2gpa unknown error %d", __func__, error));
- if (error >= 0) {
- /*
- * error = 0: the translation was successful
- * error = 1: a fault was injected into the guest
- */
- gg->fault = error;
- error = 0;
- } else {
- error = EFAULT;
- }
break;
}
case VM_ACTIVATE_CPU:
diff --git a/sys/amd64/vmm/vmm_instruction_emul.c b/sys/amd64/vmm/vmm_instruction_emul.c
index c83f3e0..9c6158a 100644
--- a/sys/amd64/vmm/vmm_instruction_emul.c
+++ b/sys/amd64/vmm/vmm_instruction_emul.c
@@ -597,13 +597,11 @@ emulate_movx(void *vm, int vcpuid, uint64_t gpa, struct vie *vie,
/*
* Helper function to calculate and validate a linear address.
- *
- * Returns 0 on success and 1 if an exception was injected into the guest.
*/
static int
get_gla(void *vm, int vcpuid, struct vie *vie, struct vm_guest_paging *paging,
int opsize, int addrsize, int prot, enum vm_reg_name seg,
- enum vm_reg_name gpr, uint64_t *gla)
+ enum vm_reg_name gpr, uint64_t *gla, int *fault)
{
struct seg_desc desc;
uint64_t cr0, val, rflags;
@@ -629,7 +627,7 @@ get_gla(void *vm, int vcpuid, struct vie *vie, struct vm_guest_paging *paging,
vm_inject_ss(vm, vcpuid, 0);
else
vm_inject_gp(vm, vcpuid);
- return (1);
+ goto guest_fault;
}
if (vie_canonical_check(paging->cpu_mode, *gla)) {
@@ -637,14 +635,19 @@ get_gla(void *vm, int vcpuid, struct vie *vie, struct vm_guest_paging *paging,
vm_inject_ss(vm, vcpuid, 0);
else
vm_inject_gp(vm, vcpuid);
- return (1);
+ goto guest_fault;
}
if (vie_alignment_check(paging->cpl, opsize, cr0, rflags, *gla)) {
vm_inject_ac(vm, vcpuid, 0);
- return (1);
+ goto guest_fault;
}
+ *fault = 0;
+ return (0);
+
+guest_fault:
+ *fault = 1;
return (0);
}
@@ -660,7 +663,7 @@ emulate_movs(void *vm, int vcpuid, uint64_t gpa, struct vie *vie,
#endif
uint64_t dstaddr, srcaddr, dstgpa, srcgpa, val;
uint64_t rcx, rdi, rsi, rflags;
- int error, opsize, seg, repeat;
+ int error, fault, opsize, seg, repeat;
opsize = (vie->op.op_byte == 0xA4) ? 1 : vie->opsize;
val = 0;
@@ -683,8 +686,10 @@ emulate_movs(void *vm, int vcpuid, uint64_t gpa, struct vie *vie,
* The count register is %rcx, %ecx or %cx depending on the
* address size of the instruction.
*/
- if ((rcx & vie_size2mask(vie->addrsize)) == 0)
- return (0);
+ if ((rcx & vie_size2mask(vie->addrsize)) == 0) {
+ error = 0;
+ goto done;
+ }
}
/*
@@ -705,13 +710,16 @@ emulate_movs(void *vm, int vcpuid, uint64_t gpa, struct vie *vie,
seg = vie->segment_override ? vie->segment_register : VM_REG_GUEST_DS;
error = get_gla(vm, vcpuid, vie, paging, opsize, vie->addrsize,
- PROT_READ, seg, VM_REG_GUEST_RSI, &srcaddr);
- if (error)
+ PROT_READ, seg, VM_REG_GUEST_RSI, &srcaddr, &fault);
+ if (error || fault)
goto done;
error = vm_copy_setup(vm, vcpuid, paging, srcaddr, opsize, PROT_READ,
- copyinfo, nitems(copyinfo));
+ copyinfo, nitems(copyinfo), &fault);
if (error == 0) {
+ if (fault)
+ goto done; /* Resume guest to handle fault */
+
/*
* case (2): read from system memory and write to mmio.
*/
@@ -720,11 +728,6 @@ emulate_movs(void *vm, int vcpuid, uint64_t gpa, struct vie *vie,
error = memwrite(vm, vcpuid, gpa, val, opsize, arg);
if (error)
goto done;
- } else if (error > 0) {
- /*
- * Resume guest execution to handle fault.
- */
- goto done;
} else {
/*
* 'vm_copy_setup()' is expected to fail for cases (3) and (4)
@@ -732,13 +735,17 @@ emulate_movs(void *vm, int vcpuid, uint64_t gpa, struct vie *vie,
*/
error = get_gla(vm, vcpuid, vie, paging, opsize, vie->addrsize,
- PROT_WRITE, VM_REG_GUEST_ES, VM_REG_GUEST_RDI, &dstaddr);
- if (error)
+ PROT_WRITE, VM_REG_GUEST_ES, VM_REG_GUEST_RDI, &dstaddr,
+ &fault);
+ if (error || fault)
goto done;
error = vm_copy_setup(vm, vcpuid, paging, dstaddr, opsize,
- PROT_WRITE, copyinfo, nitems(copyinfo));
+ PROT_WRITE, copyinfo, nitems(copyinfo), &fault);
if (error == 0) {
+ if (fault)
+ goto done; /* Resume guest to handle fault */
+
/*
* case (3): read from MMIO and write to system memory.
*
@@ -754,27 +761,29 @@ emulate_movs(void *vm, int vcpuid, uint64_t gpa, struct vie *vie,
vm_copyout(vm, vcpuid, &val, copyinfo, opsize);
vm_copy_teardown(vm, vcpuid, copyinfo, nitems(copyinfo));
- } else if (error > 0) {
- /*
- * Resume guest execution to handle fault.
- */
- goto done;
} else {
/*
* Case (4): read from and write to mmio.
+ *
+ * Commit to the MMIO read/write (with potential
+ * side-effects) only after we are sure that the
+ * instruction is not going to be restarted due
+ * to address translation faults.
*/
error = vm_gla2gpa(vm, vcpuid, paging, srcaddr,
- PROT_READ, &srcgpa);
- if (error)
- goto done;
- error = memread(vm, vcpuid, srcgpa, &val, opsize, arg);
- if (error)
+ PROT_READ, &srcgpa, &fault);
+ if (error || fault)
goto done;
error = vm_gla2gpa(vm, vcpuid, paging, dstaddr,
- PROT_WRITE, &dstgpa);
+ PROT_WRITE, &dstgpa, &fault);
+ if (error || fault)
+ goto done;
+
+ error = memread(vm, vcpuid, srcgpa, &val, opsize, arg);
if (error)
goto done;
+
error = memwrite(vm, vcpuid, dstgpa, val, opsize, arg);
if (error)
goto done;
@@ -819,10 +828,9 @@ emulate_movs(void *vm, int vcpuid, uint64_t gpa, struct vie *vie,
vm_restart_instruction(vm, vcpuid);
}
done:
- if (error < 0)
- return (EFAULT);
- else
- return (0);
+ KASSERT(error == 0 || error == EFAULT, ("%s: unexpected error %d",
+ __func__, error));
+ return (error);
}
static int
@@ -1185,7 +1193,7 @@ emulate_stack_op(void *vm, int vcpuid, uint64_t mmio_gpa, struct vie *vie,
#endif
struct seg_desc ss_desc;
uint64_t cr0, rflags, rsp, stack_gla, val;
- int error, size, stackaddrsize, pushop;
+ int error, fault, size, stackaddrsize, pushop;
val = 0;
size = vie->opsize;
@@ -1251,18 +1259,10 @@ emulate_stack_op(void *vm, int vcpuid, uint64_t mmio_gpa, struct vie *vie,
}
error = vm_copy_setup(vm, vcpuid, paging, stack_gla, size,
- pushop ? PROT_WRITE : PROT_READ, copyinfo, nitems(copyinfo));
- if (error == -1) {
- /*
- * XXX cannot return a negative error value here because it
- * ends up being the return value of the VM_RUN() ioctl and
- * is interpreted as a pseudo-error (for e.g. ERESTART).
- */
- return (EFAULT);
- } else if (error == 1) {
- /* Resume guest execution to handle page fault */
- return (0);
- }
+ pushop ? PROT_WRITE : PROT_READ, copyinfo, nitems(copyinfo),
+ &fault);
+ if (error || fault)
+ return (error);
if (pushop) {
error = memread(vm, vcpuid, mmio_gpa, &val, size, arg);
@@ -1672,7 +1672,7 @@ ptp_hold(struct vm *vm, vm_paddr_t ptpphys, size_t len, void **cookie)
int
vm_gla2gpa(struct vm *vm, int vcpuid, struct vm_guest_paging *paging,
- uint64_t gla, int prot, uint64_t *gpa)
+ uint64_t gla, int prot, uint64_t *gpa, int *guest_fault)
{
int nlevels, pfcode, ptpshift, ptpindex, retval, usermode, writable;
u_int retries;
@@ -1680,6 +1680,8 @@ vm_gla2gpa(struct vm *vm, int vcpuid, struct vm_guest_paging *paging,
uint32_t *ptpbase32, pte32;
void *cookie;
+ *guest_fault = 0;
+
usermode = (paging->cpl == 3 ? 1 : 0);
writable = prot & VM_PROT_WRITE;
cookie = NULL;
@@ -1842,18 +1844,20 @@ restart:
*gpa = pte | (gla & (pgsize - 1));
done:
ptp_release(&cookie);
+ KASSERT(retval == 0 || retval == EFAULT, ("%s: unexpected retval %d",
+ __func__, retval));
return (retval);
error:
- retval = -1;
+ retval = EFAULT;
goto done;
fault:
- retval = 1;
+ *guest_fault = 1;
goto done;
}
int
vmm_fetch_instruction(struct vm *vm, int vcpuid, struct vm_guest_paging *paging,
- uint64_t rip, int inst_length, struct vie *vie)
+ uint64_t rip, int inst_length, struct vie *vie, int *faultptr)
{
struct vm_copyinfo copyinfo[2];
int error, prot;
@@ -1863,13 +1867,14 @@ vmm_fetch_instruction(struct vm *vm, int vcpuid, struct vm_guest_paging *paging,
prot = PROT_READ | PROT_EXEC;
error = vm_copy_setup(vm, vcpuid, paging, rip, inst_length, prot,
- copyinfo, nitems(copyinfo));
- if (error == 0) {
- vm_copyin(vm, vcpuid, copyinfo, vie->inst, inst_length);
- vm_copy_teardown(vm, vcpuid, copyinfo, nitems(copyinfo));
- vie->num_valid = inst_length;
- }
- return (error);
+ copyinfo, nitems(copyinfo), faultptr);
+ if (error || *faultptr)
+ return (error);
+
+ vm_copyin(vm, vcpuid, copyinfo, vie->inst, inst_length);
+ vm_copy_teardown(vm, vcpuid, copyinfo, nitems(copyinfo));
+ vie->num_valid = inst_length;
+ return (0);
}
static int
diff --git a/sys/arm/amlogic/aml8726/aml8726_pic.c b/sys/arm/amlogic/aml8726/aml8726_pic.c
index 5ef1403..565d157 100644
--- a/sys/arm/amlogic/aml8726/aml8726_pic.c
+++ b/sys/arm/amlogic/aml8726/aml8726_pic.c
@@ -121,6 +121,8 @@ aml8726_pic_eoi(void *arg)
if (nb >= AML_PIC_NIRQS)
return;
+ arm_irq_memory_barrier(nb);
+
CSR_WRITE_4(aml8726_pic_sc, AML_PIC_STAT_CLR_REG(nb), AML_PIC_BIT(nb));
CSR_BARRIER(aml8726_pic_sc, AML_PIC_STAT_CLR_REG(nb));
@@ -265,8 +267,12 @@ arm_unmask_irq(uintptr_t nb)
if (nb >= AML_PIC_NIRQS)
return;
+ arm_irq_memory_barrier(nb);
+
mask = CSR_READ_4(aml8726_pic_sc, AML_PIC_MASK_REG(nb));
mask |= AML_PIC_BIT(nb);
CSR_WRITE_4(aml8726_pic_sc, AML_PIC_MASK_REG(nb), mask);
+
+ CSR_BARRIER(aml8726_pic_sc, AML_PIC_MASK_REG(nb));
}
#endif
diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c
index a76e18a4..3ef156b 100644
--- a/sys/arm/arm/machdep.c
+++ b/sys/arm/arm/machdep.c
@@ -114,7 +114,57 @@ __FBSDID("$FreeBSD$");
#ifdef DDB
#include <ddb/ddb.h>
-#endif
+
+#if __ARM_ARCH >= 6
+#include <machine/cpu-v6.h>
+
+DB_SHOW_COMMAND(cp15, db_show_cp15)
+{
+ u_int reg;
+
+ reg = cp15_midr_get();
+ db_printf("Cpu ID: 0x%08x\n", reg);
+ reg = cp15_ctr_get();
+ db_printf("Current Cache Lvl ID: 0x%08x\n",reg);
+
+ reg = cp15_sctlr_get();
+ db_printf("Ctrl: 0x%08x\n",reg);
+ reg = cp15_actlr_get();
+ db_printf("Aux Ctrl: 0x%08x\n",reg);
+
+ reg = cp15_id_pfr0_get();
+ db_printf("Processor Feat 0: 0x%08x\n", reg);
+ reg = cp15_id_pfr1_get();
+ db_printf("Processor Feat 1: 0x%08x\n", reg);
+ reg = cp15_id_dfr0_get();
+ db_printf("Debug Feat 0: 0x%08x\n", reg);
+ reg = cp15_id_afr0_get();
+ db_printf("Auxiliary Feat 0: 0x%08x\n", reg);
+ reg = cp15_id_mmfr0_get();
+ db_printf("Memory Model Feat 0: 0x%08x\n", reg);
+ reg = cp15_id_mmfr1_get();
+ db_printf("Memory Model Feat 1: 0x%08x\n", reg);
+ reg = cp15_id_mmfr2_get();
+ db_printf("Memory Model Feat 2: 0x%08x\n", reg);
+ reg = cp15_id_mmfr3_get();
+ db_printf("Memory Model Feat 3: 0x%08x\n", reg);
+ reg = cp15_ttbr_get();
+ db_printf("TTB0: 0x%08x\n", reg);
+}
+
+DB_SHOW_COMMAND(vtop, db_show_vtop)
+{
+ u_int reg;
+
+ if (have_addr) {
+ cp15_ats1cpr_set(addr);
+ reg = cp15_par_get();
+ db_printf("Physical address reg: 0x%08x\n",reg);
+ } else
+ db_printf("show vtop <virt_addr>\n");
+}
+#endif /* __ARM_ARCH >= 6 */
+#endif /* DDB */
#ifdef DEBUG
#define debugf(fmt, args...) printf(fmt, ##args)
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c b/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c
index ab0f901..1466313 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c
@@ -1425,7 +1425,10 @@ static int
bcm2835_cpufreq_probe(device_t dev)
{
+ if (device_get_unit(dev) != 0)
+ return (ENXIO);
device_set_desc(dev, "CPU Frequency Control");
+
return (0);
}
diff --git a/sys/arm/broadcom/bcm2835/bcm2836.c b/sys/arm/broadcom/bcm2835/bcm2836.c
index 3e89eae..58ad8e4 100644
--- a/sys/arm/broadcom/bcm2835/bcm2836.c
+++ b/sys/arm/broadcom/bcm2835/bcm2836.c
@@ -52,7 +52,9 @@ __FBSDID("$FreeBSD$");
#define ARM_LOCAL_INT_TIMER(n) (0x40 + (n) * 4)
#define ARM_LOCAL_INT_MAILBOX(n) (0x50 + (n) * 4)
#define ARM_LOCAL_INT_PENDING(n) (0x60 + (n) * 4)
-#define INT_PENDING_MASK 0x0f
+#define INT_PENDING_MASK 0x01f
+#define MAILBOX0_IRQ 4
+#define MAILBOX0_IRQEN (1 << 0)
/*
* A driver for features of the bcm2836.
@@ -141,12 +143,27 @@ void
bcm2836_mask_irq(uintptr_t irq)
{
uint32_t reg;
+#ifdef SMP
+ int cpu;
+#endif
int i;
- for (i = 0; i < 4; i++) {
- reg = bus_read_4(softc->sc_mem, ARM_LOCAL_INT_TIMER(i));
- reg &= ~(1 << irq);
- bus_write_4(softc->sc_mem, ARM_LOCAL_INT_TIMER(i), reg);
+ if (irq < MAILBOX0_IRQ) {
+ for (i = 0; i < 4; i++) {
+ reg = bus_read_4(softc->sc_mem,
+ ARM_LOCAL_INT_TIMER(i));
+ reg &= ~(1 << irq);
+ bus_write_4(softc->sc_mem,
+ ARM_LOCAL_INT_TIMER(i), reg);
+ }
+#ifdef SMP
+ } else if (irq == MAILBOX0_IRQ) {
+ /* Mailbox 0 for IPI */
+ cpu = PCPU_GET(cpuid);
+ reg = bus_read_4(softc->sc_mem, ARM_LOCAL_INT_MAILBOX(cpu));
+ reg &= ~MAILBOX0_IRQEN;
+ bus_write_4(softc->sc_mem, ARM_LOCAL_INT_MAILBOX(cpu), reg);
+#endif
}
}
@@ -154,12 +171,27 @@ void
bcm2836_unmask_irq(uintptr_t irq)
{
uint32_t reg;
+#ifdef SMP
+ int cpu;
+#endif
int i;
- for (i = 0; i < 4; i++) {
- reg = bus_read_4(softc->sc_mem, ARM_LOCAL_INT_TIMER(i));
- reg |= (1 << irq);
- bus_write_4(softc->sc_mem, ARM_LOCAL_INT_TIMER(i), reg);
+ if (irq < MAILBOX0_IRQ) {
+ for (i = 0; i < 4; i++) {
+ reg = bus_read_4(softc->sc_mem,
+ ARM_LOCAL_INT_TIMER(i));
+ reg |= (1 << irq);
+ bus_write_4(softc->sc_mem,
+ ARM_LOCAL_INT_TIMER(i), reg);
+ }
+#ifdef SMP
+ } else if (irq == MAILBOX0_IRQ) {
+ /* Mailbox 0 for IPI */
+ cpu = PCPU_GET(cpuid);
+ reg = bus_read_4(softc->sc_mem, ARM_LOCAL_INT_MAILBOX(cpu));
+ reg |= MAILBOX0_IRQEN;
+ bus_write_4(softc->sc_mem, ARM_LOCAL_INT_MAILBOX(cpu), reg);
+#endif
}
}
diff --git a/sys/arm/broadcom/bcm2835/bcm2836_mp.c b/sys/arm/broadcom/bcm2835/bcm2836_mp.c
new file mode 100644
index 0000000..177f41e
--- /dev/null
+++ b/sys/arm/broadcom/bcm2835/bcm2836_mp.c
@@ -0,0 +1,207 @@
+/*-
+ * Copyright (C) 2015 Daisuke Aoyama <aoyama@peach.ne.jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/smp.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/smp.h>
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/intr.h>
+
+#ifdef DEBUG
+#define DPRINTF(fmt, ...) do { \
+ printf("%s:%u: ", __func__, __LINE__); \
+ printf(fmt, ##__VA_ARGS__); \
+} while (0)
+#else
+#define DPRINTF(fmt, ...)
+#endif
+
+#define ARM_LOCAL_BASE 0x40000000
+#define ARM_LOCAL_SIZE 0x00001000
+
+/* mailbox registers */
+#define MBOXINTRCTRL_CORE(n) (0x00000050 + (0x04 * (n)))
+#define MBOX0SET_CORE(n) (0x00000080 + (0x10 * (n)))
+#define MBOX1SET_CORE(n) (0x00000084 + (0x10 * (n)))
+#define MBOX2SET_CORE(n) (0x00000088 + (0x10 * (n)))
+#define MBOX3SET_CORE(n) (0x0000008C + (0x10 * (n)))
+#define MBOX0CLR_CORE(n) (0x000000C0 + (0x10 * (n)))
+#define MBOX1CLR_CORE(n) (0x000000C4 + (0x10 * (n)))
+#define MBOX2CLR_CORE(n) (0x000000C8 + (0x10 * (n)))
+#define MBOX3CLR_CORE(n) (0x000000CC + (0x10 * (n)))
+
+static bus_space_handle_t bs_periph;
+
+#define BSRD4(addr) \
+ bus_space_read_4(fdtbus_bs_tag, bs_periph, (addr))
+#define BSWR4(addr, val) \
+ bus_space_write_4(fdtbus_bs_tag, bs_periph, (addr), (val))
+
+void
+platform_mp_init_secondary(void)
+{
+
+}
+
+void
+platform_mp_setmaxid(void)
+{
+
+ DPRINTF("platform_mp_setmaxid\n");
+ if (mp_ncpus != 0)
+ return;
+
+ mp_ncpus = 4;
+ mp_maxid = mp_ncpus - 1;
+ DPRINTF("mp_maxid=%d\n", mp_maxid);
+}
+
+int
+platform_mp_probe(void)
+{
+
+ DPRINTF("platform_mp_probe\n");
+ CPU_SETOF(0, &all_cpus);
+ if (mp_ncpus == 0)
+ platform_mp_setmaxid();
+ return (mp_ncpus > 1);
+}
+
+void
+platform_mp_start_ap(void)
+{
+ uint32_t val;
+ int i, retry;
+
+ DPRINTF("platform_mp_start_ap\n");
+
+ /* initialize */
+ if (bus_space_map(fdtbus_bs_tag, ARM_LOCAL_BASE, ARM_LOCAL_SIZE,
+ 0, &bs_periph) != 0)
+ panic("can't map local peripheral\n");
+ for (i = 0; i < mp_ncpus; i++) {
+ /* clear mailbox 0/3 */
+ BSWR4(MBOX0CLR_CORE(i), 0xffffffff);
+ BSWR4(MBOX3CLR_CORE(i), 0xffffffff);
+ }
+ wmb();
+
+ /* boot secondary CPUs */
+ for (i = 1; i < mp_ncpus; i++) {
+ /* set entry point to mailbox 3 */
+ BSWR4(MBOX3SET_CORE(i),
+ (uint32_t)pmap_kextract((vm_offset_t)mpentry));
+ wmb();
+
+ /* wait for bootup */
+ retry = 1000;
+ do {
+ /* check entry point */
+ val = BSRD4(MBOX3CLR_CORE(i));
+ if (val == 0)
+ break;
+ DELAY(100);
+ retry--;
+ if (retry <= 0) {
+ printf("can't start for CPU%d\n", i);
+ break;
+ }
+ } while (1);
+
+ /* dsb and sev */
+ armv7_sev();
+
+ /* recode AP in CPU map */
+ CPU_SET(i, &all_cpus);
+ }
+
+ cpu_idcache_wbinv_all();
+ cpu_l2cache_wbinv_all();
+}
+
+void
+pic_ipi_send(cpuset_t cpus, u_int ipi)
+{
+ int i;
+
+ dsb();
+ for (i = 0; i < mp_ncpus; i++) {
+ if (CPU_ISSET(i, &cpus))
+ BSWR4(MBOX0SET_CORE(i), 1 << ipi);
+ }
+ wmb();
+}
+
+int
+pic_ipi_read(int i)
+{
+ uint32_t val;
+ int cpu, ipi;
+
+ cpu = PCPU_GET(cpuid);
+ dsb();
+ if (i != -1) {
+ val = BSRD4(MBOX0CLR_CORE(cpu));
+ if (val == 0)
+ return (0);
+ ipi = ffs(val) - 1;
+ return (ipi);
+ }
+ return (0x3ff);
+}
+
+void
+pic_ipi_clear(int ipi)
+{
+ int cpu;
+
+ cpu = PCPU_GET(cpuid);
+ dsb();
+ BSWR4(MBOX0CLR_CORE(cpu), 1 << ipi);
+ wmb();
+}
+
+void
+platform_ipi_send(cpuset_t cpus, u_int ipi)
+{
+
+ pic_ipi_send(cpus, ipi);
+}
diff --git a/sys/arm/broadcom/bcm2835/files.bcm2836 b/sys/arm/broadcom/bcm2835/files.bcm2836
index f797cf7..36f4d24 100644
--- a/sys/arm/broadcom/bcm2835/files.bcm2836
+++ b/sys/arm/broadcom/bcm2835/files.bcm2836
@@ -3,3 +3,4 @@
arm/arm/generic_timer.c standard
arm/broadcom/bcm2835/bcm2836.c standard
+arm/broadcom/bcm2835/bcm2836_mp.c optional smp
diff --git a/sys/arm/broadcom/bcm2835/std.bcm2836 b/sys/arm/broadcom/bcm2835/std.bcm2836
index bb112be..862be75 100644
--- a/sys/arm/broadcom/bcm2835/std.bcm2836
+++ b/sys/arm/broadcom/bcm2835/std.bcm2836
@@ -6,6 +6,7 @@ makeoptions CONF_CFLAGS="-march=armv7a"
options SOC_BCM2836
options ARM_L2_PIPT
+options IPI_IRQ_START=76
files "../broadcom/bcm2835/files.bcm2836"
files "../broadcom/bcm2835/files.bcm283x"
diff --git a/sys/arm/conf/AML8726 b/sys/arm/conf/AML8726
index a6b4a8e..125a53d 100644
--- a/sys/arm/conf/AML8726
+++ b/sys/arm/conf/AML8726
@@ -20,7 +20,7 @@
ident AML8726
-include "std.armv6"
+include "std.armv6"
include "../amlogic/aml8726/std.aml8726"
options HZ=100
diff --git a/sys/arm/conf/APALIS-IMX6 b/sys/arm/conf/APALIS-IMX6
index ceb21c7..ce8a0d5 100644
--- a/sys/arm/conf/APALIS-IMX6
+++ b/sys/arm/conf/APALIS-IMX6
@@ -19,7 +19,7 @@
#NO_UNIVERSE
-include "IMX6"
+include "IMX6"
ident APALIS-IMX6
makeoptions MODULES_OVERRIDE=""
diff --git a/sys/arm/conf/ARMADAXP b/sys/arm/conf/ARMADAXP
index ed4aa2d..6d51c16 100644
--- a/sys/arm/conf/ARMADAXP
+++ b/sys/arm/conf/ARMADAXP
@@ -20,8 +20,8 @@
ident MV-88F78XX0
-include "std.armv6"
-include "../mv/armadaxp/std.mv78x60"
+include "std.armv6"
+include "../mv/armadaxp/std.mv78x60"
options SOC_MV_ARMADAXP
diff --git a/sys/arm/conf/ARNDALE b/sys/arm/conf/ARNDALE
index 964f9e4..1c16d13 100644
--- a/sys/arm/conf/ARNDALE
+++ b/sys/arm/conf/ARNDALE
@@ -19,7 +19,7 @@
#NO_UNIVERSE
-include "EXYNOS5250"
+include "EXYNOS5250"
ident ARNDALE
#FDT
diff --git a/sys/arm/conf/ARNDALE-OCTA b/sys/arm/conf/ARNDALE-OCTA
index ad937ee..a4faaa0 100644
--- a/sys/arm/conf/ARNDALE-OCTA
+++ b/sys/arm/conf/ARNDALE-OCTA
@@ -19,7 +19,7 @@
#NO_UNIVERSE
-include "EXYNOS5420"
+include "EXYNOS5420"
ident ARNDALE-OCTA
#FDT
diff --git a/sys/arm/conf/ATMEL b/sys/arm/conf/ATMEL
index 2e8da7d..c3b6035 100644
--- a/sys/arm/conf/ATMEL
+++ b/sys/arm/conf/ATMEL
@@ -6,8 +6,8 @@
ident ATMEL
-include "std.arm"
-include "../at91/std.atmel"
+include "std.arm"
+include "../at91/std.atmel"
# Typical values for most SoCs and board configurations. Will not work for
# at91sam9g45 or on some boards with non u-boot boot loaders.
diff --git a/sys/arm/conf/AVILA b/sys/arm/conf/AVILA
index b356b35..fd4d62a 100644
--- a/sys/arm/conf/AVILA
+++ b/sys/arm/conf/AVILA
@@ -20,10 +20,10 @@
ident AVILA
-include "std.arm"
-include "../xscale/ixp425/std.ixp425"
+include "std.arm"
+include "../xscale/ixp425/std.ixp425"
# NB: memory mapping is defined in std.avila
-include "../xscale/ixp425/std.avila"
+include "../xscale/ixp425/std.avila"
options XSCALE_CACHE_READ_WRITE_ALLOCATE
#To statically compile in device wiring instead of /boot/device.hints
hints "AVILA.hints" # Default places to look for devices.
diff --git a/sys/arm/conf/BEAGLEBONE b/sys/arm/conf/BEAGLEBONE
index 997a62e..97e2d3d 100644
--- a/sys/arm/conf/BEAGLEBONE
+++ b/sys/arm/conf/BEAGLEBONE
@@ -23,8 +23,8 @@
ident BEAGLEBONE
-include "std.armv6"
-include "../ti/am335x/std.am335x"
+include "std.armv6"
+include "../ti/am335x/std.am335x"
makeoptions MODULES_EXTRA="dtb/am335x"
diff --git a/sys/arm/conf/BWCT b/sys/arm/conf/BWCT
index d483a00..a6f8e49 100644
--- a/sys/arm/conf/BWCT
+++ b/sys/arm/conf/BWCT
@@ -21,10 +21,10 @@
ident BWCT
-include "std.arm"
+include "std.arm"
options VERBOSE_INIT_ARM
-include "../at91/std.bwct"
+include "../at91/std.bwct"
#To statically compile in device wiring instead of /boot/device.hints
hints "BWCT.hints"
diff --git a/sys/arm/conf/CAMBRIA b/sys/arm/conf/CAMBRIA
index 1cf7fb9..c25521b 100644
--- a/sys/arm/conf/CAMBRIA
+++ b/sys/arm/conf/CAMBRIA
@@ -20,10 +20,10 @@
ident CAMBRIA
-include "std.arm"
-include "../xscale/ixp425/std.ixp435"
+include "std.arm"
+include "../xscale/ixp425/std.ixp435"
# NB: memory mapping is defined in std.avila
-include "../xscale/ixp425/std.avila"
+include "../xscale/ixp425/std.avila"
options XSCALE_CACHE_READ_WRITE_ALLOCATE
#To statically compile in device wiring instead of /boot/device.hints
hints "CAMBRIA.hints" # Default places to look for devices.
diff --git a/sys/arm/conf/CHROMEBOOK b/sys/arm/conf/CHROMEBOOK
index 9459151..059f243 100644
--- a/sys/arm/conf/CHROMEBOOK
+++ b/sys/arm/conf/CHROMEBOOK
@@ -17,7 +17,7 @@
#
# $FreeBSD$
-include "EXYNOS5250"
+include "EXYNOS5250"
ident CHROMEBOOK
hints "CHROMEBOOK.hints"
diff --git a/sys/arm/conf/CHROMEBOOK-PEACH-PIT b/sys/arm/conf/CHROMEBOOK-PEACH-PIT
index e01128c..87284c2 100644
--- a/sys/arm/conf/CHROMEBOOK-PEACH-PIT
+++ b/sys/arm/conf/CHROMEBOOK-PEACH-PIT
@@ -19,7 +19,7 @@
#NO_UNIVERSE
-include "EXYNOS5420"
+include "EXYNOS5420"
ident CHROMEBOOK-PEACH-PIT
hints "CHROMEBOOK-PEACH-PIT.hints"
diff --git a/sys/arm/conf/CHROMEBOOK-SNOW b/sys/arm/conf/CHROMEBOOK-SNOW
index e9242d1..aee3dc0 100644
--- a/sys/arm/conf/CHROMEBOOK-SNOW
+++ b/sys/arm/conf/CHROMEBOOK-SNOW
@@ -19,7 +19,7 @@
#NO_UNIVERSE
-include "CHROMEBOOK"
+include "CHROMEBOOK"
ident CHROMEBOOK-SNOW
#FDT
diff --git a/sys/arm/conf/CHROMEBOOK-SPRING b/sys/arm/conf/CHROMEBOOK-SPRING
index 1b791ac..9714d34 100644
--- a/sys/arm/conf/CHROMEBOOK-SPRING
+++ b/sys/arm/conf/CHROMEBOOK-SPRING
@@ -19,7 +19,7 @@
#NO_UNIVERSE
-include "CHROMEBOOK"
+include "CHROMEBOOK"
ident CHROMEBOOK-SPRING
#FDT
diff --git a/sys/arm/conf/CNS11XXNAS b/sys/arm/conf/CNS11XXNAS
index d906a2b..710a471 100644
--- a/sys/arm/conf/CNS11XXNAS
+++ b/sys/arm/conf/CNS11XXNAS
@@ -20,14 +20,14 @@
ident CNS11XXNAS
-include "std.arm"
+include "std.arm"
#options PHYSADDR=0x10000000
#options KERNPHYSADDR=0x10200000
#options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm
#options FLASHADDR=0x50000000
#options LOADERRAMADDR=0x00000000
-include "../cavium/cns11xx/std.econa"
+include "../cavium/cns11xx/std.econa"
makeoptions MODULES_OVERRIDE=""
diff --git a/sys/arm/conf/COLIBRI-VF50 b/sys/arm/conf/COLIBRI-VF50
index 9f73f69..81581f6 100644
--- a/sys/arm/conf/COLIBRI-VF50
+++ b/sys/arm/conf/COLIBRI-VF50
@@ -19,7 +19,7 @@
#NO_UNIVERSE
-include "VYBRID"
+include "VYBRID"
ident COLIBRI-VF50
#FDT
diff --git a/sys/arm/conf/COSMIC b/sys/arm/conf/COSMIC
index 72ae5c2..61b99a7 100644
--- a/sys/arm/conf/COSMIC
+++ b/sys/arm/conf/COSMIC
@@ -19,7 +19,7 @@
#NO_UNIVERSE
-include "VYBRID"
+include "VYBRID"
ident COSMIC
#FDT
diff --git a/sys/arm/conf/CRB b/sys/arm/conf/CRB
index f5cc932..69b0ebd 100644
--- a/sys/arm/conf/CRB
+++ b/sys/arm/conf/CRB
@@ -19,13 +19,13 @@
ident CRB
-include "std.arm"
+include "std.arm"
options PHYSADDR=0x00000000
options KERNPHYSADDR=0x00200000
options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm
options COUNTS_PER_SEC=400000000
-include "../xscale/i8134x/std.crb"
+include "../xscale/i8134x/std.crb"
makeoptions MODULES_OVERRIDE=""
#makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
diff --git a/sys/arm/conf/CUBIEBOARD b/sys/arm/conf/CUBIEBOARD
index 8f856bd..26283d4 100644
--- a/sys/arm/conf/CUBIEBOARD
+++ b/sys/arm/conf/CUBIEBOARD
@@ -21,8 +21,8 @@
ident CUBIEBOARD
-include "std.armv6"
-include "../allwinner/std.a10"
+include "std.armv6"
+include "../allwinner/std.a10"
options HZ=100
options SCHED_4BSD # 4BSD scheduler
diff --git a/sys/arm/conf/CUBIEBOARD2 b/sys/arm/conf/CUBIEBOARD2
index 15d028f..45311c3 100644
--- a/sys/arm/conf/CUBIEBOARD2
+++ b/sys/arm/conf/CUBIEBOARD2
@@ -21,8 +21,8 @@
ident CUBIEBOARD2
-include "std.armv6"
-include "../allwinner/a20/std.a20"
+include "std.armv6"
+include "../allwinner/a20/std.a20"
options HZ=100
options SCHED_ULE # ULE scheduler
diff --git a/sys/arm/conf/DB-78XXX b/sys/arm/conf/DB-78XXX
index 2e7fa36..e59e426 100644
--- a/sys/arm/conf/DB-78XXX
+++ b/sys/arm/conf/DB-78XXX
@@ -5,8 +5,8 @@
#
ident DB-88F78XX
-include "std.arm"
-include "../mv/discovery/std.db78xxx"
+include "std.arm"
+include "../mv/discovery/std.db78xxx"
options SOC_MV_DISCOVERY
diff --git a/sys/arm/conf/DB-88F5XXX b/sys/arm/conf/DB-88F5XXX
index 7cc06a0..f1729f0 100644
--- a/sys/arm/conf/DB-88F5XXX
+++ b/sys/arm/conf/DB-88F5XXX
@@ -5,8 +5,8 @@
#
ident DB-88F5XXX
-include "std.arm"
-include "../mv/orion/std.db88f5xxx"
+include "std.arm"
+include "../mv/orion/std.db88f5xxx"
options SOC_MV_ORION
diff --git a/sys/arm/conf/DB-88F6XXX b/sys/arm/conf/DB-88F6XXX
index afec0e7..4018bcd 100644
--- a/sys/arm/conf/DB-88F6XXX
+++ b/sys/arm/conf/DB-88F6XXX
@@ -5,8 +5,8 @@
#
ident DB-88F6XXX
-include "std.arm"
-include "../mv/kirkwood/std.db88f6xxx"
+include "std.arm"
+include "../mv/kirkwood/std.db88f6xxx"
options SOC_MV_KIRKWOOD
diff --git a/sys/arm/conf/DIGI-CCWMX53 b/sys/arm/conf/DIGI-CCWMX53
index 20dec9c..65239c1 100644
--- a/sys/arm/conf/DIGI-CCWMX53
+++ b/sys/arm/conf/DIGI-CCWMX53
@@ -19,7 +19,7 @@
#NO_UNIVERSE
-include "IMX53"
+include "IMX53"
ident DIGI-CCWMX53
makeoptions WITHOUT_MODULES="ahc"
diff --git a/sys/arm/conf/DOCKSTAR b/sys/arm/conf/DOCKSTAR
index c6308cd..9e73980 100644
--- a/sys/arm/conf/DOCKSTAR
+++ b/sys/arm/conf/DOCKSTAR
@@ -21,8 +21,8 @@
ident DOCKSTAR
-include "std.arm"
-include "../mv/kirkwood/std.db88f6xxx"
+include "std.arm"
+include "../mv/kirkwood/std.db88f6xxx"
makeoptions FDT_DTS_FILE=dockstar.dts
diff --git a/sys/arm/conf/DREAMPLUG-1001 b/sys/arm/conf/DREAMPLUG-1001
index f97b564..f44599e 100644
--- a/sys/arm/conf/DREAMPLUG-1001
+++ b/sys/arm/conf/DREAMPLUG-1001
@@ -24,8 +24,8 @@
ident DREAMPLUG-1001
-include "std.arm"
-include "../mv/kirkwood/std.db88f6xxx"
+include "std.arm"
+include "../mv/kirkwood/std.db88f6xxx"
makeoptions FDT_DTS_FILE=dreamplug-1001.dts
diff --git a/sys/arm/conf/EA3250 b/sys/arm/conf/EA3250
index bcb8276..8f13505 100644
--- a/sys/arm/conf/EA3250
+++ b/sys/arm/conf/EA3250
@@ -5,8 +5,8 @@
#
ident EA3250
-include "std.arm"
-include "../lpc/std.lpc"
+include "std.arm"
+include "../lpc/std.lpc"
hints "EA3250.hints"
makeoptions MODULES_OVERRIDE=""
diff --git a/sys/arm/conf/EB9200 b/sys/arm/conf/EB9200
index bf0c41b..afcc530 100644
--- a/sys/arm/conf/EB9200
+++ b/sys/arm/conf/EB9200
@@ -16,8 +16,8 @@
ident EB9200
-include "std.arm"
-include "../at91/std.eb9200"
+include "std.arm"
+include "../at91/std.eb9200"
# The AT91 platform doesn't use /boot/loader, so we have to statically wire
# hints.
hints "EB9200.hints"
diff --git a/sys/arm/conf/EFIKA_MX b/sys/arm/conf/EFIKA_MX
index 81edae8..dc22943 100644
--- a/sys/arm/conf/EFIKA_MX
+++ b/sys/arm/conf/EFIKA_MX
@@ -20,7 +20,7 @@
ident EFIKA_MX
-include "std.armv6"
+include "std.armv6"
include "../freescale/imx/std.imx51"
makeoptions WITHOUT_MODULES="ahc"
diff --git a/sys/arm/conf/EP80219 b/sys/arm/conf/EP80219
index 6f2bef8..301849c 100644
--- a/sys/arm/conf/EP80219
+++ b/sys/arm/conf/EP80219
@@ -19,13 +19,13 @@
ident EP80219
-include "std.arm"
+include "std.arm"
options PHYSADDR=0xa0000000
options KERNPHYSADDR=0xa0200000
options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm
#options ARM32_NEW_VM_LAYOUT
-include "../xscale/i80321/std.ep80219"
+include "../xscale/i80321/std.ep80219"
makeoptions MODULES_OVERRIDE=""
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
diff --git a/sys/arm/conf/ETHERNUT5 b/sys/arm/conf/ETHERNUT5
index f01ea0d..c91869a 100644
--- a/sys/arm/conf/ETHERNUT5
+++ b/sys/arm/conf/ETHERNUT5
@@ -21,8 +21,8 @@
ident ETHERNUT5
-include "std.arm"
-include "../at91/std.ethernut5"
+include "std.arm"
+include "../at91/std.ethernut5"
# To statically compile in device wiring instead of /boot/device.hints
hints "ETHERNUT5.hints"
diff --git a/sys/arm/conf/EXYNOS5.common b/sys/arm/conf/EXYNOS5.common
index 2f96935..0bd6ad6 100644
--- a/sys/arm/conf/EXYNOS5.common
+++ b/sys/arm/conf/EXYNOS5.common
@@ -20,7 +20,7 @@
makeoptions WERROR="-Werror"
-include "std.armv6"
+include "std.armv6"
options HZ=100
options SCHED_ULE # ULE scheduler
options PREEMPTION # Enable kernel thread preemption
diff --git a/sys/arm/conf/EXYNOS5250 b/sys/arm/conf/EXYNOS5250
index 156d856..e22239f 100644
--- a/sys/arm/conf/EXYNOS5250
+++ b/sys/arm/conf/EXYNOS5250
@@ -18,8 +18,8 @@
# $FreeBSD$
ident EXYNOS5250
-include "EXYNOS5.common"
-include "../samsung/exynos/std.exynos5250"
+include "EXYNOS5.common"
+include "../samsung/exynos/std.exynos5250"
#FDT
options FDT
diff --git a/sys/arm/conf/EXYNOS5420 b/sys/arm/conf/EXYNOS5420
index 0f2c2c7..b55151a 100644
--- a/sys/arm/conf/EXYNOS5420
+++ b/sys/arm/conf/EXYNOS5420
@@ -18,8 +18,8 @@
# $FreeBSD$
ident EXYNOS5420
-include "EXYNOS5.common"
-include "../samsung/exynos/std.exynos5420"
+include "EXYNOS5.common"
+include "../samsung/exynos/std.exynos5420"
#FDT
options FDT
diff --git a/sys/arm/conf/GUMSTIX b/sys/arm/conf/GUMSTIX
index 9ba6155..048bd3c 100644
--- a/sys/arm/conf/GUMSTIX
+++ b/sys/arm/conf/GUMSTIX
@@ -19,7 +19,7 @@
# $FreeBSD$
ident GUMSTIX
-include "std.arm"
+include "std.arm"
cpu CPU_XSCALE_PXA2X0
# This probably wants to move somewhere else. Maybe we can create a basic
@@ -31,7 +31,7 @@ options PHYSADDR=0xa0000000
options KERNPHYSADDR=0xa0200000
options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm
-include "../xscale/pxa/std.pxa"
+include "../xscale/pxa/std.pxa"
makeoptions MODULES_OVERRIDE=""
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
diff --git a/sys/arm/conf/HL200 b/sys/arm/conf/HL200
index 8d22da5..43a8148 100644
--- a/sys/arm/conf/HL200
+++ b/sys/arm/conf/HL200
@@ -21,8 +21,8 @@
ident HL200
-include "std.arm"
-include "../at91/std.hl200"
+include "std.arm"
+include "../at91/std.hl200"
#To statically compile in device wiring instead of /boot/device.hints
hints "KB920X.hints"
diff --git a/sys/arm/conf/HL201 b/sys/arm/conf/HL201
index 4ec6da3..2eed9d5 100644
--- a/sys/arm/conf/HL201
+++ b/sys/arm/conf/HL201
@@ -21,8 +21,8 @@
ident HL201
-include "std.arm"
-include "../at91/std.hl201"
+include "std.arm"
+include "../at91/std.hl201"
makeoptions MODULES_OVERRIDE=""
diff --git a/sys/arm/conf/IMX53 b/sys/arm/conf/IMX53
index 3275bfc..d07d6ad 100644
--- a/sys/arm/conf/IMX53
+++ b/sys/arm/conf/IMX53
@@ -20,7 +20,7 @@
ident IMX53
-include "std.armv6"
+include "std.armv6"
include "../freescale/imx/std.imx53"
options SOC_IMX53
diff --git a/sys/arm/conf/IMX53-QSB b/sys/arm/conf/IMX53-QSB
index fdde591..5fa907c 100644
--- a/sys/arm/conf/IMX53-QSB
+++ b/sys/arm/conf/IMX53-QSB
@@ -19,7 +19,7 @@
#NO_UNIVERSE
-include "IMX53"
+include "IMX53"
ident IMX53-QSB
options HZ=250 # 4ms scheduling quantum
diff --git a/sys/arm/conf/IMX6 b/sys/arm/conf/IMX6
index 5ead99b..332681a 100644
--- a/sys/arm/conf/IMX6
+++ b/sys/arm/conf/IMX6
@@ -19,7 +19,7 @@
# $FreeBSD$
ident IMX6
-include "std.armv6"
+include "std.armv6"
include "../freescale/imx/std.imx6"
options SOC_IMX6
diff --git a/sys/arm/conf/IQ31244 b/sys/arm/conf/IQ31244
index 403a0c2..ae8eae8 100644
--- a/sys/arm/conf/IQ31244
+++ b/sys/arm/conf/IQ31244
@@ -19,14 +19,14 @@
ident IQ31244
-include "std.arm"
+include "std.arm"
options PHYSADDR=0xa0000000
options KERNPHYSADDR=0xa0200000
options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm
options FLASHADDR=0xf0000000
options LOADERRAMADDR=0x00000000
-include "../xscale/i80321/std.iq31244"
+include "../xscale/i80321/std.iq31244"
makeoptions MODULES_OVERRIDE=""
#makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
diff --git a/sys/arm/conf/KB920X b/sys/arm/conf/KB920X
index 6d91ad8..79be31a 100644
--- a/sys/arm/conf/KB920X
+++ b/sys/arm/conf/KB920X
@@ -22,8 +22,8 @@
ident KB920X
-include "std.arm"
-include "../at91/std.kb920x"
+include "std.arm"
+include "../at91/std.kb920x"
# The AT91 platform doesn't use /boot/loader, so we have to statically wire
# hints.
hints "KB920X.hints"
diff --git a/sys/arm/conf/LN2410SBC b/sys/arm/conf/LN2410SBC
index ae3c62a..a154c32 100644
--- a/sys/arm/conf/LN2410SBC
+++ b/sys/arm/conf/LN2410SBC
@@ -19,7 +19,7 @@
ident LN2410SBC
-include "std.arm"
+include "std.arm"
include "../samsung/s3c2xx0/std.ln2410sbc"
#To statically compile in device wiring instead of /boot/device.hints
#hints "GENERIC.hints" # Default places to look for devices.
diff --git a/sys/arm/conf/NSLU b/sys/arm/conf/NSLU
index 00a2902..665910a 100644
--- a/sys/arm/conf/NSLU
+++ b/sys/arm/conf/NSLU
@@ -21,7 +21,7 @@
ident NSLU
-include "std.arm"
+include "std.arm"
# XXX What is defined in std.avila does not exactly match the following:
#options PHYSADDR=0x10000000
#options KERNPHYSADDR=0x10200000
@@ -29,9 +29,9 @@ include "std.arm"
#options FLASHADDR=0x50000000
#options LOADERRAMADDR=0x00000000
-include "../xscale/ixp425/std.ixp425"
+include "../xscale/ixp425/std.ixp425"
# NB: memory mapping is defined in std.avila (see also comment above)
-include "../xscale/ixp425/std.avila"
+include "../xscale/ixp425/std.avila"
options XSCALE_CACHE_READ_WRITE_ALLOCATE
#To statically compile in device wiring instead of /boot/device.hints
hints "NSLU.hints" # Default places to look for devices.
diff --git a/sys/arm/conf/PANDABOARD b/sys/arm/conf/PANDABOARD
index e58c953..41e2900 100644
--- a/sys/arm/conf/PANDABOARD
+++ b/sys/arm/conf/PANDABOARD
@@ -27,7 +27,7 @@ ident PANDABOARD
hints "PANDABOARD.hints"
-include "std.armv6"
+include "std.armv6"
include "../ti/omap4/pandaboard/std.pandaboard"
options HZ=100
diff --git a/sys/arm/conf/QILA9G20 b/sys/arm/conf/QILA9G20
index 2f9b609..1d6bff9 100644
--- a/sys/arm/conf/QILA9G20
+++ b/sys/arm/conf/QILA9G20
@@ -22,8 +22,8 @@
ident QILA9G20
-include "std.arm"
-include "../at91/std.qila9g20"
+include "std.arm"
+include "../at91/std.qila9g20"
#To statically compile in device wiring instead of /boot/device.hints
hints "QILA9G20.hints"
diff --git a/sys/arm/conf/QUARTZ b/sys/arm/conf/QUARTZ
index 04f1b5c..9c98185 100644
--- a/sys/arm/conf/QUARTZ
+++ b/sys/arm/conf/QUARTZ
@@ -19,7 +19,7 @@
#NO_UNIVERSE
-include "VYBRID"
+include "VYBRID"
ident QUARTZ
#FDT
diff --git a/sys/arm/conf/RADXA b/sys/arm/conf/RADXA
index ad5eadf..8801f67 100644
--- a/sys/arm/conf/RADXA
+++ b/sys/arm/conf/RADXA
@@ -20,7 +20,7 @@
#NO_UNIVERSE
-include "RK3188"
+include "RK3188"
ident RADXA
# Flattened Device Tree
diff --git a/sys/arm/conf/RADXA-LITE b/sys/arm/conf/RADXA-LITE
index c07462d..7252941 100644
--- a/sys/arm/conf/RADXA-LITE
+++ b/sys/arm/conf/RADXA-LITE
@@ -20,7 +20,7 @@
#NO_UNIVERSE
-include "RK3188"
+include "RK3188"
ident RADXA-LITE
# Flattened Device Tree
diff --git a/sys/arm/conf/RK3188 b/sys/arm/conf/RK3188
index 46bc334..9afa7ab 100644
--- a/sys/arm/conf/RK3188
+++ b/sys/arm/conf/RK3188
@@ -20,8 +20,8 @@
ident RK3188
-include "std.armv6"
-include "../rockchip/std.rk30xx"
+include "std.armv6"
+include "../rockchip/std.rk30xx"
options HZ=100
options SCHED_ULE # ULE scheduler
diff --git a/sys/arm/conf/RPI-B b/sys/arm/conf/RPI-B
index 309a499..9193bca 100644
--- a/sys/arm/conf/RPI-B
+++ b/sys/arm/conf/RPI-B
@@ -20,9 +20,9 @@
ident RPI-B
-include "std.armv6"
-include "../broadcom/bcm2835/std.rpi"
-include "../broadcom/bcm2835/std.bcm2835"
+include "std.armv6"
+include "../broadcom/bcm2835/std.rpi"
+include "../broadcom/bcm2835/std.bcm2835"
options HZ=100
options SCHED_4BSD # 4BSD scheduler
diff --git a/sys/arm/conf/RPI2 b/sys/arm/conf/RPI2
index dbb67d9..27caac9 100644
--- a/sys/arm/conf/RPI2
+++ b/sys/arm/conf/RPI2
@@ -20,12 +20,13 @@
ident RPI2
-include "std.armv6"
-include "../broadcom/bcm2835/std.rpi"
-include "../broadcom/bcm2835/std.bcm2836"
+include "std.armv6"
+include "../broadcom/bcm2835/std.rpi"
+include "../broadcom/bcm2835/std.bcm2836"
options HZ=100
-options SCHED_4BSD # 4BSD scheduler
+options SCHED_ULE # ULE scheduler
+options SMP # Enable multiple cores
options PLATFORM
# Debugging for use in -current
diff --git a/sys/arm/conf/SAM9260EK b/sys/arm/conf/SAM9260EK
index 30680c5..a3c7759 100644
--- a/sys/arm/conf/SAM9260EK
+++ b/sys/arm/conf/SAM9260EK
@@ -21,8 +21,8 @@
ident SAM9260EK
-include "std.arm"
-include "../at91/std.sam9260ek"
+include "std.arm"
+include "../at91/std.sam9260ek"
# To statically compile in device wiring instead of /boot/device.hints
hints "SAM9260EK.hints"
diff --git a/sys/arm/conf/SAM9G20EK b/sys/arm/conf/SAM9G20EK
index 4d961c7..e12a143 100644
--- a/sys/arm/conf/SAM9G20EK
+++ b/sys/arm/conf/SAM9G20EK
@@ -19,8 +19,8 @@
ident SAM9G20EK
-include "std.arm"
-include "../at91/std.sam9g20ek"
+include "std.arm"
+include "../at91/std.sam9g20ek"
#To statically compile in device wiring instead of /boot/device.hints
hints "SAM9G20EK.hints"
diff --git a/sys/arm/conf/SAM9X25EK b/sys/arm/conf/SAM9X25EK
index 49afe99..08dc1f5 100644
--- a/sys/arm/conf/SAM9X25EK
+++ b/sys/arm/conf/SAM9X25EK
@@ -21,8 +21,8 @@
ident SAM9X25EK
-include "std.arm"
-include "../at91/std.sam9x25ek"
+include "std.arm"
+include "../at91/std.sam9x25ek"
#To statically compile in device wiring instead of /boot/device.hints
hints "SAM9G20EK.hints"
diff --git a/sys/arm/conf/SHEEVAPLUG b/sys/arm/conf/SHEEVAPLUG
index e013e75..9797cc0 100644
--- a/sys/arm/conf/SHEEVAPLUG
+++ b/sys/arm/conf/SHEEVAPLUG
@@ -6,8 +6,8 @@
#NO_UNIVERSE
ident SHEEVAPLUG
-include "std.arm"
-include "../mv/kirkwood/std.db88f6xxx"
+include "std.arm"
+include "../mv/kirkwood/std.db88f6xxx"
options SOC_MV_KIRKWOOD
diff --git a/sys/arm/conf/SN9G45 b/sys/arm/conf/SN9G45
index bf46503..e85d613 100644
--- a/sys/arm/conf/SN9G45
+++ b/sys/arm/conf/SN9G45
@@ -21,8 +21,8 @@
ident SN9G45
-include "std.arm"
-include "../at91/std.sn9g45"
+include "std.arm"
+include "../at91/std.sn9g45"
#To statically compile in device wiring instead of /boot/device.hints
#hints "SN9G45.hints"
diff --git a/sys/arm/conf/SOCKIT.common b/sys/arm/conf/SOCKIT.common
index eb87fd6..ff817f8 100644
--- a/sys/arm/conf/SOCKIT.common
+++ b/sys/arm/conf/SOCKIT.common
@@ -18,7 +18,7 @@
#
# $FreeBSD$
-include "std.armv6"
+include "std.armv6"
include "../altera/socfpga/std.socfpga"
makeoptions MODULES_OVERRIDE=""
diff --git a/sys/arm/conf/TS7800 b/sys/arm/conf/TS7800
index ab9fe5b..1a565c4 100644
--- a/sys/arm/conf/TS7800
+++ b/sys/arm/conf/TS7800
@@ -5,8 +5,8 @@
#
ident TS7800
-include "std.arm"
-include "../mv/orion/std.ts7800"
+include "std.arm"
+include "../mv/orion/std.ts7800"
options SOC_MV_ORION
diff --git a/sys/arm/conf/VERSATILEPB b/sys/arm/conf/VERSATILEPB
index 182e56c..d1fc77a 100644
--- a/sys/arm/conf/VERSATILEPB
+++ b/sys/arm/conf/VERSATILEPB
@@ -22,7 +22,7 @@ ident VERSATILEPB
machine arm armv6
cpu CPU_ARM1176
-include "std.armv6"
+include "std.armv6"
files "../versatile/files.versatile"
makeoptions MODULES_OVERRIDE=""
diff --git a/sys/arm/conf/VIRT b/sys/arm/conf/VIRT
index 0f67b84..58efec4 100644
--- a/sys/arm/conf/VIRT
+++ b/sys/arm/conf/VIRT
@@ -20,8 +20,8 @@
ident VIRT
-include "std.armv6"
-include "../qemu/std.virt"
+include "std.armv6"
+include "../qemu/std.virt"
options HZ=100
options SCHED_4BSD # 4BSD scheduler
diff --git a/sys/arm/conf/VYBRID b/sys/arm/conf/VYBRID
index 8fb0198..7e01756 100644
--- a/sys/arm/conf/VYBRID
+++ b/sys/arm/conf/VYBRID
@@ -19,8 +19,8 @@
# $FreeBSD$
ident VYBRID
-include "std.armv6"
-include "../freescale/vybrid/std.vybrid"
+include "std.armv6"
+include "../freescale/vybrid/std.vybrid"
makeoptions WERROR="-Werror"
diff --git a/sys/arm/conf/ZEDBOARD b/sys/arm/conf/ZEDBOARD
index 7c108a1..3c31b74 100644
--- a/sys/arm/conf/ZEDBOARD
+++ b/sys/arm/conf/ZEDBOARD
@@ -21,7 +21,7 @@
ident ZEDBOARD
-include "std.armv6"
+include "std.armv6"
include "../xilinx/zedboard/std.zedboard"
options SCHED_ULE # ULE scheduler
diff --git a/sys/arm/include/armreg.h b/sys/arm/include/armreg.h
index 3163ba5..9358703 100644
--- a/sys/arm/include/armreg.h
+++ b/sys/arm/include/armreg.h
@@ -346,6 +346,9 @@
#define CPUV7_CT_xSIZE_ASSOC(x) (((x) >> 3) & 0x3ff) /* associativity */
#define CPUV7_CT_xSIZE_SET(x) (((x) >> 13) & 0x7fff) /* num sets */
+#define CPUV7_L2CTLR_NPROC_SHIFT 24
+#define CPUV7_L2CTLR_NPROC(r) ((((r) >> CPUV7_L2CTLR_NPROC_SHIFT) & 3) + 1)
+
#define CPU_CLIDR_CTYPE(reg,x) (((reg) >> ((x) * 3)) & 0x7)
#define CPU_CLIDR_LOUIS(reg) (((reg) >> 21) & 0x7)
#define CPU_CLIDR_LOC(reg) (((reg) >> 24) & 0x7)
diff --git a/sys/arm/include/cpu-v6.h b/sys/arm/include/cpu-v6.h
index 6c226a3..b0d7a7f 100644
--- a/sys/arm/include/cpu-v6.h
+++ b/sys/arm/include/cpu-v6.h
@@ -143,6 +143,13 @@ _RF0(cp15_ttbr_get, CP15_TTBR0(%0))
_RF0(cp15_dfar_get, CP15_DFAR(%0))
#if __ARM_ARCH >= 7
_RF0(cp15_ifar_get, CP15_IFAR(%0))
+_RF0(cp15_l2ctlr_get, CP15_L2CTLR(%0))
+#endif
+#if __ARM_ARCH >= 6
+_RF0(cp15_actlr_get, CP15_ACTLR(%0))
+_WF1(cp15_ats1cpr_set, CP15_ATS1CPR(%0));
+_RF0(cp15_par_get, CP15_PAR);
+_RF0(cp15_sctlr_get, CP15_SCTLR(%0))
#endif
/*CPU id registers */
diff --git a/sys/arm/include/pl310.h b/sys/arm/include/pl310.h
index f7c75e9..fd75d44 100644
--- a/sys/arm/include/pl310.h
+++ b/sys/arm/include/pl310.h
@@ -133,7 +133,7 @@
#define PREFETCH_CTRL_DATA_PREFETCH (1 << 28)
#define PREFETCH_CTRL_INSTR_PREFETCH (1 << 29)
#define PREFETCH_CTRL_DL (1 << 30)
-#define PL310_POWER_CTRL 0xF60
+#define PL310_POWER_CTRL 0xF80
#define POWER_CTRL_ENABLE_GATING (1 << 0)
#define POWER_CTRL_ENABLE_STANDBY (1 << 1)
diff --git a/sys/arm/include/sysreg.h b/sys/arm/include/sysreg.h
index f29991a..fb13487 100644
--- a/sys/arm/include/sysreg.h
+++ b/sys/arm/include/sysreg.h
@@ -212,6 +212,7 @@
#if __ARM_ARCH == 6 && defined(CPU_ARM1176)
#define CP15_PMCCNTR(rr) p15, 0, rr, c15, c12, 1 /* PM Cycle Count Register */
#elif __ARM_ARCH > 6
+#define CP15_L2CTLR(rr) p15, 1, rr, c9, c0, 2 /* L2 Control Register */
#define CP15_PMCR(rr) p15, 0, rr, c9, c12, 0 /* Performance Monitor Control Register */
#define CP15_PMCNTENSET(rr) p15, 0, rr, c9, c12, 1 /* PM Count Enable Set Register */
#define CP15_PMCNTENCLR(rr) p15, 0, rr, c9, c12, 2 /* PM Count Enable Clear Register */
diff --git a/sys/arm/ti/ti_i2c.c b/sys/arm/ti/ti_i2c.c
index ad688f3..3337032 100644
--- a/sys/arm/ti/ti_i2c.c
+++ b/sys/arm/ti/ti_i2c.c
@@ -953,6 +953,17 @@ static device_method_t ti_i2c_methods[] = {
DEVMETHOD(device_attach, ti_i2c_attach),
DEVMETHOD(device_detach, ti_i2c_detach),
+ /* Bus interface */
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+ DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
+ DEVMETHOD(bus_release_resource, bus_generic_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource),
+ DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource),
+ DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
+
/* OFW methods */
DEVMETHOD(ofw_bus_get_node, ti_i2c_get_node),
diff --git a/sys/arm64/arm64/busdma_bounce.c b/sys/arm64/arm64/busdma_bounce.c
new file mode 100644
index 0000000..477c819
--- /dev/null
+++ b/sys/arm64/arm64/busdma_bounce.c
@@ -0,0 +1,1080 @@
+/*-
+ * Copyright (c) 1997, 1998 Justin T. Gibbs.
+ * Copyright (c) 2015 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Semihalf
+ * under 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,
+ * without modification, immediately at the beginning of the file.
+ * 2. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/bus.h>
+#include <sys/interrupt.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/lock.h>
+#include <sys/proc.h>
+#include <sys/memdesc.h>
+#include <sys/mutex.h>
+#include <sys/sysctl.h>
+#include <sys/uio.h>
+
+#include <vm/vm.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_page.h>
+#include <vm/vm_map.h>
+
+#include <machine/atomic.h>
+#include <machine/bus.h>
+#include <machine/md_var.h>
+#include <arm64/include/bus_dma_impl.h>
+
+#define MAX_BPAGES 4096
+
+enum {
+ BUS_DMA_COULD_BOUNCE = 0x01,
+ BUS_DMA_MIN_ALLOC_COMP = 0x02,
+ BUS_DMA_KMEM_ALLOC = 0x04,
+};
+
+struct bounce_zone;
+
+struct bus_dma_tag {
+ struct bus_dma_tag_common common;
+ int map_count;
+ int bounce_flags;
+ bus_dma_segment_t *segments;
+ struct bounce_zone *bounce_zone;
+};
+
+struct bounce_page {
+ vm_offset_t vaddr; /* kva of bounce buffer */
+ bus_addr_t busaddr; /* Physical address */
+ vm_offset_t datavaddr; /* kva of client data */
+ bus_addr_t dataaddr; /* client physical address */
+ bus_size_t datacount; /* client data count */
+ STAILQ_ENTRY(bounce_page) links;
+};
+
+int busdma_swi_pending;
+
+struct bounce_zone {
+ STAILQ_ENTRY(bounce_zone) links;
+ STAILQ_HEAD(bp_list, bounce_page) bounce_page_list;
+ int total_bpages;
+ int free_bpages;
+ int reserved_bpages;
+ int active_bpages;
+ int total_bounced;
+ int total_deferred;
+ int map_count;
+ bus_size_t alignment;
+ bus_addr_t lowaddr;
+ char zoneid[8];
+ char lowaddrid[20];
+ struct sysctl_ctx_list sysctl_tree;
+ struct sysctl_oid *sysctl_tree_top;
+};
+
+static struct mtx bounce_lock;
+static int total_bpages;
+static int busdma_zonecount;
+static STAILQ_HEAD(, bounce_zone) bounce_zone_list;
+
+static SYSCTL_NODE(_hw, OID_AUTO, busdma, CTLFLAG_RD, 0, "Busdma parameters");
+SYSCTL_INT(_hw_busdma, OID_AUTO, total_bpages, CTLFLAG_RD, &total_bpages, 0,
+ "Total bounce pages");
+
+struct bus_dmamap {
+ struct bp_list bpages;
+ int pagesneeded;
+ int pagesreserved;
+ bus_dma_tag_t dmat;
+ struct memdesc mem;
+ bus_dmamap_callback_t *callback;
+ void *callback_arg;
+ STAILQ_ENTRY(bus_dmamap) links;
+};
+
+static STAILQ_HEAD(, bus_dmamap) bounce_map_waitinglist;
+static STAILQ_HEAD(, bus_dmamap) bounce_map_callbacklist;
+static struct bus_dmamap nobounce_dmamap;
+
+static void init_bounce_pages(void *dummy);
+static int alloc_bounce_zone(bus_dma_tag_t dmat);
+static int alloc_bounce_pages(bus_dma_tag_t dmat, u_int numpages);
+static int reserve_bounce_pages(bus_dma_tag_t dmat, bus_dmamap_t map,
+ int commit);
+static bus_addr_t add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map,
+ vm_offset_t vaddr, bus_addr_t addr, bus_size_t size);
+static void free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage);
+int run_filter(bus_dma_tag_t dmat, bus_addr_t paddr);
+static void _bus_dmamap_count_pages(bus_dma_tag_t dmat, bus_dmamap_t map,
+ pmap_t pmap, void *buf, bus_size_t buflen, int flags);
+static void _bus_dmamap_count_phys(bus_dma_tag_t dmat, bus_dmamap_t map,
+ vm_paddr_t buf, bus_size_t buflen, int flags);
+static int _bus_dmamap_reserve_pages(bus_dma_tag_t dmat, bus_dmamap_t map,
+ int flags);
+
+/*
+ * Allocate a device specific dma_tag.
+ */
+static int
+bounce_bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment,
+ bus_addr_t boundary, bus_addr_t lowaddr, bus_addr_t highaddr,
+ bus_dma_filter_t *filter, void *filterarg, bus_size_t maxsize,
+ int nsegments, bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc,
+ void *lockfuncarg, bus_dma_tag_t *dmat)
+{
+ bus_dma_tag_t newtag;
+ int error;
+
+ *dmat = NULL;
+ error = common_bus_dma_tag_create(parent != NULL ? &parent->common :
+ NULL, alignment, boundary, lowaddr, highaddr, filter, filterarg,
+ maxsize, nsegments, maxsegsz, flags, lockfunc, lockfuncarg,
+ sizeof (struct bus_dma_tag), (void **)&newtag);
+ if (error != 0)
+ return (error);
+
+ newtag->common.impl = &bus_dma_bounce_impl;
+ newtag->map_count = 0;
+ newtag->segments = NULL;
+
+ if (parent != NULL && ((newtag->common.filter != NULL) ||
+ ((parent->bounce_flags & BUS_DMA_COULD_BOUNCE) != 0)))
+ newtag->bounce_flags |= BUS_DMA_COULD_BOUNCE;
+
+ if (newtag->common.lowaddr < ptoa((vm_paddr_t)Maxmem) ||
+ newtag->common.alignment > 1)
+ newtag->bounce_flags |= BUS_DMA_COULD_BOUNCE;
+
+ if (((newtag->bounce_flags & BUS_DMA_COULD_BOUNCE) != 0) &&
+ (flags & BUS_DMA_ALLOCNOW) != 0) {
+ struct bounce_zone *bz;
+
+ /* Must bounce */
+ if ((error = alloc_bounce_zone(newtag)) != 0) {
+ free(newtag, M_DEVBUF);
+ return (error);
+ }
+ bz = newtag->bounce_zone;
+
+ if (ptoa(bz->total_bpages) < maxsize) {
+ int pages;
+
+ pages = atop(maxsize) - bz->total_bpages;
+
+ /* Add pages to our bounce pool */
+ if (alloc_bounce_pages(newtag, pages) < pages)
+ error = ENOMEM;
+ }
+ /* Performed initial allocation */
+ newtag->bounce_flags |= BUS_DMA_MIN_ALLOC_COMP;
+ } else
+ error = 0;
+
+ if (error != 0)
+ free(newtag, M_DEVBUF);
+ else
+ *dmat = newtag;
+ CTR4(KTR_BUSDMA, "%s returned tag %p tag flags 0x%x error %d",
+ __func__, newtag, (newtag != NULL ? newtag->common.flags : 0),
+ error);
+ return (error);
+}
+
+static int
+bounce_bus_dma_tag_destroy(bus_dma_tag_t dmat)
+{
+ bus_dma_tag_t dmat_copy, parent;
+ int error;
+
+ error = 0;
+ dmat_copy = dmat;
+
+ if (dmat != NULL) {
+ if (dmat->map_count != 0) {
+ error = EBUSY;
+ goto out;
+ }
+ while (dmat != NULL) {
+ parent = (bus_dma_tag_t)dmat->common.parent;
+ atomic_subtract_int(&dmat->common.ref_count, 1);
+ if (dmat->common.ref_count == 0) {
+ if (dmat->segments != NULL)
+ free(dmat->segments, M_DEVBUF);
+ free(dmat, M_DEVBUF);
+ /*
+ * Last reference count, so
+ * release our reference
+ * count on our parent.
+ */
+ dmat = parent;
+ } else
+ dmat = NULL;
+ }
+ }
+out:
+ CTR3(KTR_BUSDMA, "%s tag %p error %d", __func__, dmat_copy, error);
+ return (error);
+}
+
+/*
+ * Allocate a handle for mapping from kva/uva/physical
+ * address space into bus device space.
+ */
+static int
+bounce_bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp)
+{
+ struct bounce_zone *bz;
+ int error, maxpages, pages;
+
+ error = 0;
+
+ if (dmat->segments == NULL) {
+ dmat->segments = (bus_dma_segment_t *)malloc(
+ sizeof(bus_dma_segment_t) * dmat->common.nsegments,
+ M_DEVBUF, M_NOWAIT);
+ if (dmat->segments == NULL) {
+ CTR3(KTR_BUSDMA, "%s: tag %p error %d",
+ __func__, dmat, ENOMEM);
+ return (ENOMEM);
+ }
+ }
+
+ /*
+ * Bouncing might be required if the driver asks for an active
+ * exclusion region, a data alignment that is stricter than 1, and/or
+ * an active address boundary.
+ */
+ if (dmat->bounce_flags & BUS_DMA_COULD_BOUNCE) {
+ /* Must bounce */
+ if (dmat->bounce_zone == NULL) {
+ if ((error = alloc_bounce_zone(dmat)) != 0)
+ return (error);
+ }
+ bz = dmat->bounce_zone;
+
+ *mapp = (bus_dmamap_t)malloc(sizeof(**mapp), M_DEVBUF,
+ M_NOWAIT | M_ZERO);
+ if (*mapp == NULL) {
+ CTR3(KTR_BUSDMA, "%s: tag %p error %d",
+ __func__, dmat, ENOMEM);
+ return (ENOMEM);
+ }
+
+ /* Initialize the new map */
+ STAILQ_INIT(&((*mapp)->bpages));
+
+ /*
+ * Attempt to add pages to our pool on a per-instance
+ * basis up to a sane limit.
+ */
+ if (dmat->common.alignment > 1)
+ maxpages = MAX_BPAGES;
+ else
+ maxpages = MIN(MAX_BPAGES, Maxmem -
+ atop(dmat->common.lowaddr));
+ if ((dmat->bounce_flags & BUS_DMA_MIN_ALLOC_COMP) == 0 ||
+ (bz->map_count > 0 && bz->total_bpages < maxpages)) {
+ pages = MAX(atop(dmat->common.maxsize), 1);
+ pages = MIN(maxpages - bz->total_bpages, pages);
+ pages = MAX(pages, 1);
+ if (alloc_bounce_pages(dmat, pages) < pages)
+ error = ENOMEM;
+ if ((dmat->bounce_flags & BUS_DMA_MIN_ALLOC_COMP)
+ == 0) {
+ if (error == 0) {
+ dmat->bounce_flags |=
+ BUS_DMA_MIN_ALLOC_COMP;
+ }
+ } else
+ error = 0;
+ }
+ bz->map_count++;
+ } else {
+ *mapp = NULL;
+ }
+ if (error == 0)
+ dmat->map_count++;
+ CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
+ __func__, dmat, dmat->common.flags, error);
+ return (error);
+}
+
+/*
+ * Destroy a handle for mapping from kva/uva/physical
+ * address space into bus device space.
+ */
+static int
+bounce_bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map)
+{
+
+ if (map != NULL && map != &nobounce_dmamap) {
+ if (STAILQ_FIRST(&map->bpages) != NULL) {
+ CTR3(KTR_BUSDMA, "%s: tag %p error %d",
+ __func__, dmat, EBUSY);
+ return (EBUSY);
+ }
+ if (dmat->bounce_zone)
+ dmat->bounce_zone->map_count--;
+ free(map, M_DEVBUF);
+ }
+ dmat->map_count--;
+ CTR2(KTR_BUSDMA, "%s: tag %p error 0", __func__, dmat);
+ return (0);
+}
+
+
+/*
+ * Allocate a piece of memory that can be efficiently mapped into
+ * bus device space based on the constraints lited in the dma tag.
+ * A dmamap to for use with dmamap_load is also allocated.
+ */
+static int
+bounce_bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
+ bus_dmamap_t *mapp)
+{
+ /*
+ * XXX ARM64TODO:
+ * This bus_dma implementation requires IO-Coherent architecutre.
+ * If IO-Coherency is not guaranteed, the BUS_DMA_COHERENT flag has
+ * to be implented using non-cacheable memory.
+ */
+
+ vm_memattr_t attr;
+ int mflags;
+
+ if (flags & BUS_DMA_NOWAIT)
+ mflags = M_NOWAIT;
+ else
+ mflags = M_WAITOK;
+
+ /* If we succeed, no mapping/bouncing will be required */
+ *mapp = NULL;
+
+ if (dmat->segments == NULL) {
+ dmat->segments = (bus_dma_segment_t *)malloc(
+ sizeof(bus_dma_segment_t) * dmat->common.nsegments,
+ M_DEVBUF, mflags);
+ if (dmat->segments == NULL) {
+ CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
+ __func__, dmat, dmat->common.flags, ENOMEM);
+ return (ENOMEM);
+ }
+ }
+ if (flags & BUS_DMA_ZERO)
+ mflags |= M_ZERO;
+ if (flags & BUS_DMA_NOCACHE)
+ attr = VM_MEMATTR_UNCACHEABLE;
+ else
+ attr = VM_MEMATTR_DEFAULT;
+
+ /*
+ * XXX:
+ * (dmat->alignment < dmat->maxsize) is just a quick hack; the exact
+ * alignment guarantees of malloc need to be nailed down, and the
+ * code below should be rewritten to take that into account.
+ *
+ * In the meantime, we'll warn the user if malloc gets it wrong.
+ */
+ if ((dmat->common.maxsize <= PAGE_SIZE) &&
+ (dmat->common.alignment < dmat->common.maxsize) &&
+ dmat->common.lowaddr >= ptoa((vm_paddr_t)Maxmem) &&
+ attr == VM_MEMATTR_DEFAULT) {
+ *vaddr = malloc(dmat->common.maxsize, M_DEVBUF, mflags);
+ } else if (dmat->common.nsegments >= btoc(dmat->common.maxsize) &&
+ dmat->common.alignment <= PAGE_SIZE &&
+ (dmat->common.boundary == 0 ||
+ dmat->common.boundary >= dmat->common.lowaddr)) {
+ /* Page-based multi-segment allocations allowed */
+ *vaddr = (void *)kmem_alloc_attr(kernel_arena,
+ dmat->common.maxsize, mflags, 0ul, dmat->common.lowaddr,
+ attr);
+ dmat->bounce_flags |= BUS_DMA_KMEM_ALLOC;
+ } else {
+ *vaddr = (void *)kmem_alloc_contig(kernel_arena,
+ dmat->common.maxsize, mflags, 0ul, dmat->common.lowaddr,
+ dmat->common.alignment != 0 ? dmat->common.alignment : 1ul,
+ dmat->common.boundary, attr);
+ dmat->bounce_flags |= BUS_DMA_KMEM_ALLOC;
+ }
+ if (*vaddr == NULL) {
+ CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
+ __func__, dmat, dmat->common.flags, ENOMEM);
+ return (ENOMEM);
+ } else if (vtophys(*vaddr) & (dmat->common.alignment - 1)) {
+ printf("bus_dmamem_alloc failed to align memory properly.\n");
+ }
+ CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
+ __func__, dmat, dmat->common.flags, 0);
+ return (0);
+}
+
+/*
+ * Free a piece of memory and it's allociated dmamap, that was allocated
+ * via bus_dmamem_alloc. Make the same choice for free/contigfree.
+ */
+static void
+bounce_bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map)
+{
+ /*
+ * dmamem does not need to be bounced, so the map should be
+ * NULL and the BUS_DMA_KMEM_ALLOC flag cleared if malloc()
+ * was used and set if kmem_alloc_contig() was used.
+ */
+ if (map != NULL)
+ panic("bus_dmamem_free: Invalid map freed\n");
+ if ((dmat->bounce_flags & BUS_DMA_KMEM_ALLOC) == 0)
+ free(vaddr, M_DEVBUF);
+ else
+ kmem_free(kernel_arena, (vm_offset_t)vaddr,
+ dmat->common.maxsize);
+ CTR3(KTR_BUSDMA, "%s: tag %p flags 0x%x", __func__, dmat,
+ dmat->bounce_flags);
+}
+
+static void
+_bus_dmamap_count_phys(bus_dma_tag_t dmat, bus_dmamap_t map, vm_paddr_t buf,
+ bus_size_t buflen, int flags)
+{
+ bus_addr_t curaddr;
+ bus_size_t sgsize;
+
+ if ((map != &nobounce_dmamap && map->pagesneeded == 0)) {
+ /*
+ * Count the number of bounce pages
+ * needed in order to complete this transfer
+ */
+ curaddr = buf;
+ while (buflen != 0) {
+ sgsize = MIN(buflen, dmat->common.maxsegsz);
+ if (bus_dma_run_filter(&dmat->common, curaddr)) {
+ sgsize = MIN(sgsize, PAGE_SIZE);
+ map->pagesneeded++;
+ }
+ curaddr += sgsize;
+ buflen -= sgsize;
+ }
+ CTR1(KTR_BUSDMA, "pagesneeded= %d\n", map->pagesneeded);
+ }
+}
+
+static void
+_bus_dmamap_count_pages(bus_dma_tag_t dmat, bus_dmamap_t map, pmap_t pmap,
+ void *buf, bus_size_t buflen, int flags)
+{
+ vm_offset_t vaddr;
+ vm_offset_t vendaddr;
+ bus_addr_t paddr;
+ bus_size_t sg_len;
+
+ if ((map != &nobounce_dmamap && map->pagesneeded == 0)) {
+ CTR4(KTR_BUSDMA, "lowaddr= %d Maxmem= %d, boundary= %d, "
+ "alignment= %d", dmat->common.lowaddr,
+ ptoa((vm_paddr_t)Maxmem),
+ dmat->common.boundary, dmat->common.alignment);
+ CTR3(KTR_BUSDMA, "map= %p, nobouncemap= %p, pagesneeded= %d",
+ map, &nobounce_dmamap, map->pagesneeded);
+ /*
+ * Count the number of bounce pages
+ * needed in order to complete this transfer
+ */
+ vaddr = (vm_offset_t)buf;
+ vendaddr = (vm_offset_t)buf + buflen;
+
+ while (vaddr < vendaddr) {
+ sg_len = PAGE_SIZE - ((vm_offset_t)vaddr & PAGE_MASK);
+ if (pmap == kernel_pmap)
+ paddr = pmap_kextract(vaddr);
+ else
+ paddr = pmap_extract(pmap, vaddr);
+ if (bus_dma_run_filter(&dmat->common, paddr) != 0) {
+ sg_len = roundup2(sg_len,
+ dmat->common.alignment);
+ map->pagesneeded++;
+ }
+ vaddr += sg_len;
+ }
+ CTR1(KTR_BUSDMA, "pagesneeded= %d\n", map->pagesneeded);
+ }
+}
+
+static int
+_bus_dmamap_reserve_pages(bus_dma_tag_t dmat, bus_dmamap_t map, int flags)
+{
+
+ /* Reserve Necessary Bounce Pages */
+ mtx_lock(&bounce_lock);
+ if (flags & BUS_DMA_NOWAIT) {
+ if (reserve_bounce_pages(dmat, map, 0) != 0) {
+ mtx_unlock(&bounce_lock);
+ return (ENOMEM);
+ }
+ } else {
+ if (reserve_bounce_pages(dmat, map, 1) != 0) {
+ /* Queue us for resources */
+ STAILQ_INSERT_TAIL(&bounce_map_waitinglist, map, links);
+ mtx_unlock(&bounce_lock);
+ return (EINPROGRESS);
+ }
+ }
+ mtx_unlock(&bounce_lock);
+
+ return (0);
+}
+
+/*
+ * Add a single contiguous physical range to the segment list.
+ */
+static int
+_bus_dmamap_addseg(bus_dma_tag_t dmat, bus_dmamap_t map, bus_addr_t curaddr,
+ bus_size_t sgsize, bus_dma_segment_t *segs, int *segp)
+{
+ bus_addr_t baddr, bmask;
+ int seg;
+
+ /*
+ * Make sure we don't cross any boundaries.
+ */
+ bmask = ~(dmat->common.boundary - 1);
+ if (dmat->common.boundary > 0) {
+ baddr = (curaddr + dmat->common.boundary) & bmask;
+ if (sgsize > (baddr - curaddr))
+ sgsize = (baddr - curaddr);
+ }
+
+ /*
+ * Insert chunk into a segment, coalescing with
+ * previous segment if possible.
+ */
+ seg = *segp;
+ if (seg == -1) {
+ seg = 0;
+ segs[seg].ds_addr = curaddr;
+ segs[seg].ds_len = sgsize;
+ } else {
+ if (curaddr == segs[seg].ds_addr + segs[seg].ds_len &&
+ (segs[seg].ds_len + sgsize) <= dmat->common.maxsegsz &&
+ (dmat->common.boundary == 0 ||
+ (segs[seg].ds_addr & bmask) == (curaddr & bmask)))
+ segs[seg].ds_len += sgsize;
+ else {
+ if (++seg >= dmat->common.nsegments)
+ return (0);
+ segs[seg].ds_addr = curaddr;
+ segs[seg].ds_len = sgsize;
+ }
+ }
+ *segp = seg;
+ return (sgsize);
+}
+
+/*
+ * Utility function to load a physical buffer. segp contains
+ * the starting segment on entrace, and the ending segment on exit.
+ */
+static int
+bounce_bus_dmamap_load_phys(bus_dma_tag_t dmat, bus_dmamap_t map,
+ vm_paddr_t buf, bus_size_t buflen, int flags, bus_dma_segment_t *segs,
+ int *segp)
+{
+ bus_size_t sgsize;
+ bus_addr_t curaddr;
+ int error;
+
+ if (map == NULL)
+ map = &nobounce_dmamap;
+
+ if (segs == NULL)
+ segs = dmat->segments;
+
+ if ((dmat->bounce_flags & BUS_DMA_COULD_BOUNCE) != 0) {
+ _bus_dmamap_count_phys(dmat, map, buf, buflen, flags);
+ if (map->pagesneeded != 0) {
+ error = _bus_dmamap_reserve_pages(dmat, map, flags);
+ if (error)
+ return (error);
+ }
+ }
+
+ while (buflen > 0) {
+ curaddr = buf;
+ sgsize = MIN(buflen, dmat->common.maxsegsz);
+ if (((dmat->bounce_flags & BUS_DMA_COULD_BOUNCE) != 0) &&
+ map->pagesneeded != 0 &&
+ bus_dma_run_filter(&dmat->common, curaddr)) {
+ sgsize = MIN(sgsize, PAGE_SIZE);
+ curaddr = add_bounce_page(dmat, map, 0, curaddr,
+ sgsize);
+ }
+ sgsize = _bus_dmamap_addseg(dmat, map, curaddr, sgsize, segs,
+ segp);
+ if (sgsize == 0)
+ break;
+ buf += sgsize;
+ buflen -= sgsize;
+ }
+
+ /*
+ * Did we fit?
+ */
+ return (buflen != 0 ? EFBIG : 0); /* XXX better return value here? */
+}
+
+/*
+ * Utility function to load a linear buffer. segp contains
+ * the starting segment on entrace, and the ending segment on exit.
+ */
+static int
+bounce_bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
+ bus_size_t buflen, pmap_t pmap, int flags, bus_dma_segment_t *segs,
+ int *segp)
+{
+ bus_size_t sgsize, max_sgsize;
+ bus_addr_t curaddr;
+ vm_offset_t vaddr;
+ int error;
+
+ if (map == NULL)
+ map = &nobounce_dmamap;
+
+ if (segs == NULL)
+ segs = dmat->segments;
+
+ if ((dmat->bounce_flags & BUS_DMA_COULD_BOUNCE) != 0) {
+ _bus_dmamap_count_pages(dmat, map, pmap, buf, buflen, flags);
+ if (map->pagesneeded != 0) {
+ error = _bus_dmamap_reserve_pages(dmat, map, flags);
+ if (error)
+ return (error);
+ }
+ }
+
+ vaddr = (vm_offset_t)buf;
+ while (buflen > 0) {
+ /*
+ * Get the physical address for this segment.
+ */
+ if (pmap == kernel_pmap)
+ curaddr = pmap_kextract(vaddr);
+ else
+ curaddr = pmap_extract(pmap, vaddr);
+
+ /*
+ * Compute the segment size, and adjust counts.
+ */
+ max_sgsize = MIN(buflen, dmat->common.maxsegsz);
+ sgsize = PAGE_SIZE - ((vm_offset_t)curaddr & PAGE_MASK);
+ if (((dmat->bounce_flags & BUS_DMA_COULD_BOUNCE) != 0) &&
+ map->pagesneeded != 0 &&
+ bus_dma_run_filter(&dmat->common, curaddr)) {
+ sgsize = roundup2(sgsize, dmat->common.alignment);
+ sgsize = MIN(sgsize, max_sgsize);
+ curaddr = add_bounce_page(dmat, map, vaddr, curaddr,
+ sgsize);
+ } else {
+ sgsize = MIN(sgsize, max_sgsize);
+ }
+ sgsize = _bus_dmamap_addseg(dmat, map, curaddr, sgsize, segs,
+ segp);
+ if (sgsize == 0)
+ break;
+ vaddr += sgsize;
+ buflen -= sgsize;
+ }
+
+ /*
+ * Did we fit?
+ */
+ return (buflen != 0 ? EFBIG : 0); /* XXX better return value here? */
+}
+
+static void
+bounce_bus_dmamap_waitok(bus_dma_tag_t dmat, bus_dmamap_t map,
+ struct memdesc *mem, bus_dmamap_callback_t *callback, void *callback_arg)
+{
+
+ if (map == NULL)
+ return;
+ map->mem = *mem;
+ map->dmat = dmat;
+ map->callback = callback;
+ map->callback_arg = callback_arg;
+}
+
+static bus_dma_segment_t *
+bounce_bus_dmamap_complete(bus_dma_tag_t dmat, bus_dmamap_t map,
+ bus_dma_segment_t *segs, int nsegs, int error)
+{
+
+ if (segs == NULL)
+ segs = dmat->segments;
+ return (segs);
+}
+
+/*
+ * Release the mapping held by map.
+ */
+static void
+bounce_bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map)
+{
+ struct bounce_page *bpage;
+
+ while ((bpage = STAILQ_FIRST(&map->bpages)) != NULL) {
+ STAILQ_REMOVE_HEAD(&map->bpages, links);
+ free_bounce_page(dmat, bpage);
+ }
+}
+
+static void
+bounce_bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map,
+ bus_dmasync_op_t op)
+{
+ struct bounce_page *bpage;
+
+ /*
+ * XXX ARM64TODO:
+ * This bus_dma implementation requires IO-Coherent architecutre.
+ * If IO-Coherency is not guaranteed, cache operations have to be
+ * added to this function.
+ */
+
+ if ((bpage = STAILQ_FIRST(&map->bpages)) != NULL) {
+ /*
+ * Handle data bouncing. We might also
+ * want to add support for invalidating
+ * the caches on broken hardware
+ */
+ CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x op 0x%x "
+ "performing bounce", __func__, dmat,
+ dmat->common.flags, op);
+
+ if ((op & BUS_DMASYNC_PREWRITE) != 0) {
+ while (bpage != NULL) {
+ if (bpage->datavaddr != 0) {
+ bcopy((void *)bpage->datavaddr,
+ (void *)bpage->vaddr,
+ bpage->datacount);
+ } else {
+ physcopyout(bpage->dataaddr,
+ (void *)bpage->vaddr,
+ bpage->datacount);
+ }
+ bpage = STAILQ_NEXT(bpage, links);
+ }
+ dmat->bounce_zone->total_bounced++;
+ }
+
+ if ((op & BUS_DMASYNC_POSTREAD) != 0) {
+ while (bpage != NULL) {
+ if (bpage->datavaddr != 0) {
+ bcopy((void *)bpage->vaddr,
+ (void *)bpage->datavaddr,
+ bpage->datacount);
+ } else {
+ physcopyin((void *)bpage->vaddr,
+ bpage->dataaddr,
+ bpage->datacount);
+ }
+ bpage = STAILQ_NEXT(bpage, links);
+ }
+ dmat->bounce_zone->total_bounced++;
+ }
+ }
+}
+
+static void
+init_bounce_pages(void *dummy __unused)
+{
+
+ total_bpages = 0;
+ STAILQ_INIT(&bounce_zone_list);
+ STAILQ_INIT(&bounce_map_waitinglist);
+ STAILQ_INIT(&bounce_map_callbacklist);
+ mtx_init(&bounce_lock, "bounce pages lock", NULL, MTX_DEF);
+}
+SYSINIT(bpages, SI_SUB_LOCK, SI_ORDER_ANY, init_bounce_pages, NULL);
+
+static struct sysctl_ctx_list *
+busdma_sysctl_tree(struct bounce_zone *bz)
+{
+ return (&bz->sysctl_tree);
+}
+
+static struct sysctl_oid *
+busdma_sysctl_tree_top(struct bounce_zone *bz)
+{
+ return (bz->sysctl_tree_top);
+}
+
+static int
+alloc_bounce_zone(bus_dma_tag_t dmat)
+{
+ struct bounce_zone *bz;
+
+ /* Check to see if we already have a suitable zone */
+ STAILQ_FOREACH(bz, &bounce_zone_list, links) {
+ if ((dmat->common.alignment <= bz->alignment) &&
+ (dmat->common.lowaddr >= bz->lowaddr)) {
+ dmat->bounce_zone = bz;
+ return (0);
+ }
+ }
+
+ if ((bz = (struct bounce_zone *)malloc(sizeof(*bz), M_DEVBUF,
+ M_NOWAIT | M_ZERO)) == NULL)
+ return (ENOMEM);
+
+ STAILQ_INIT(&bz->bounce_page_list);
+ bz->free_bpages = 0;
+ bz->reserved_bpages = 0;
+ bz->active_bpages = 0;
+ bz->lowaddr = dmat->common.lowaddr;
+ bz->alignment = MAX(dmat->common.alignment, PAGE_SIZE);
+ bz->map_count = 0;
+ snprintf(bz->zoneid, 8, "zone%d", busdma_zonecount);
+ busdma_zonecount++;
+ snprintf(bz->lowaddrid, 18, "%#jx", (uintmax_t)bz->lowaddr);
+ STAILQ_INSERT_TAIL(&bounce_zone_list, bz, links);
+ dmat->bounce_zone = bz;
+
+ sysctl_ctx_init(&bz->sysctl_tree);
+ bz->sysctl_tree_top = SYSCTL_ADD_NODE(&bz->sysctl_tree,
+ SYSCTL_STATIC_CHILDREN(_hw_busdma), OID_AUTO, bz->zoneid,
+ CTLFLAG_RD, 0, "");
+ if (bz->sysctl_tree_top == NULL) {
+ sysctl_ctx_free(&bz->sysctl_tree);
+ return (0); /* XXX error code? */
+ }
+
+ SYSCTL_ADD_INT(busdma_sysctl_tree(bz),
+ SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
+ "total_bpages", CTLFLAG_RD, &bz->total_bpages, 0,
+ "Total bounce pages");
+ SYSCTL_ADD_INT(busdma_sysctl_tree(bz),
+ SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
+ "free_bpages", CTLFLAG_RD, &bz->free_bpages, 0,
+ "Free bounce pages");
+ SYSCTL_ADD_INT(busdma_sysctl_tree(bz),
+ SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
+ "reserved_bpages", CTLFLAG_RD, &bz->reserved_bpages, 0,
+ "Reserved bounce pages");
+ SYSCTL_ADD_INT(busdma_sysctl_tree(bz),
+ SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
+ "active_bpages", CTLFLAG_RD, &bz->active_bpages, 0,
+ "Active bounce pages");
+ SYSCTL_ADD_INT(busdma_sysctl_tree(bz),
+ SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
+ "total_bounced", CTLFLAG_RD, &bz->total_bounced, 0,
+ "Total bounce requests");
+ SYSCTL_ADD_INT(busdma_sysctl_tree(bz),
+ SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
+ "total_deferred", CTLFLAG_RD, &bz->total_deferred, 0,
+ "Total bounce requests that were deferred");
+ SYSCTL_ADD_STRING(busdma_sysctl_tree(bz),
+ SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
+ "lowaddr", CTLFLAG_RD, bz->lowaddrid, 0, "");
+ SYSCTL_ADD_UAUTO(busdma_sysctl_tree(bz),
+ SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
+ "alignment", CTLFLAG_RD, &bz->alignment, "");
+
+ return (0);
+}
+
+static int
+alloc_bounce_pages(bus_dma_tag_t dmat, u_int numpages)
+{
+ struct bounce_zone *bz;
+ int count;
+
+ bz = dmat->bounce_zone;
+ count = 0;
+ while (numpages > 0) {
+ struct bounce_page *bpage;
+
+ bpage = (struct bounce_page *)malloc(sizeof(*bpage), M_DEVBUF,
+ M_NOWAIT | M_ZERO);
+
+ if (bpage == NULL)
+ break;
+ bpage->vaddr = (vm_offset_t)contigmalloc(PAGE_SIZE, M_DEVBUF,
+ M_NOWAIT, 0ul, bz->lowaddr, PAGE_SIZE, 0);
+ if (bpage->vaddr == 0) {
+ free(bpage, M_DEVBUF);
+ break;
+ }
+ bpage->busaddr = pmap_kextract(bpage->vaddr);
+ mtx_lock(&bounce_lock);
+ STAILQ_INSERT_TAIL(&bz->bounce_page_list, bpage, links);
+ total_bpages++;
+ bz->total_bpages++;
+ bz->free_bpages++;
+ mtx_unlock(&bounce_lock);
+ count++;
+ numpages--;
+ }
+ return (count);
+}
+
+static int
+reserve_bounce_pages(bus_dma_tag_t dmat, bus_dmamap_t map, int commit)
+{
+ struct bounce_zone *bz;
+ int pages;
+
+ mtx_assert(&bounce_lock, MA_OWNED);
+ bz = dmat->bounce_zone;
+ pages = MIN(bz->free_bpages, map->pagesneeded - map->pagesreserved);
+ if (commit == 0 && map->pagesneeded > (map->pagesreserved + pages))
+ return (map->pagesneeded - (map->pagesreserved + pages));
+ bz->free_bpages -= pages;
+ bz->reserved_bpages += pages;
+ map->pagesreserved += pages;
+ pages = map->pagesneeded - map->pagesreserved;
+
+ return (pages);
+}
+
+static bus_addr_t
+add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr,
+ bus_addr_t addr, bus_size_t size)
+{
+ struct bounce_zone *bz;
+ struct bounce_page *bpage;
+
+ KASSERT(dmat->bounce_zone != NULL, ("no bounce zone in dma tag"));
+ KASSERT(map != NULL && map != &nobounce_dmamap,
+ ("add_bounce_page: bad map %p", map));
+
+ bz = dmat->bounce_zone;
+ if (map->pagesneeded == 0)
+ panic("add_bounce_page: map doesn't need any pages");
+ map->pagesneeded--;
+
+ if (map->pagesreserved == 0)
+ panic("add_bounce_page: map doesn't need any pages");
+ map->pagesreserved--;
+
+ mtx_lock(&bounce_lock);
+ bpage = STAILQ_FIRST(&bz->bounce_page_list);
+ if (bpage == NULL)
+ panic("add_bounce_page: free page list is empty");
+
+ STAILQ_REMOVE_HEAD(&bz->bounce_page_list, links);
+ bz->reserved_bpages--;
+ bz->active_bpages++;
+ mtx_unlock(&bounce_lock);
+
+ if (dmat->common.flags & BUS_DMA_KEEP_PG_OFFSET) {
+ /* Page offset needs to be preserved. */
+ bpage->vaddr |= addr & PAGE_MASK;
+ bpage->busaddr |= addr & PAGE_MASK;
+ }
+ bpage->datavaddr = vaddr;
+ bpage->dataaddr = addr;
+ bpage->datacount = size;
+ STAILQ_INSERT_TAIL(&(map->bpages), bpage, links);
+ return (bpage->busaddr);
+}
+
+static void
+free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage)
+{
+ struct bus_dmamap *map;
+ struct bounce_zone *bz;
+
+ bz = dmat->bounce_zone;
+ bpage->datavaddr = 0;
+ bpage->datacount = 0;
+ if (dmat->common.flags & BUS_DMA_KEEP_PG_OFFSET) {
+ /*
+ * Reset the bounce page to start at offset 0. Other uses
+ * of this bounce page may need to store a full page of
+ * data and/or assume it starts on a page boundary.
+ */
+ bpage->vaddr &= ~PAGE_MASK;
+ bpage->busaddr &= ~PAGE_MASK;
+ }
+
+ mtx_lock(&bounce_lock);
+ STAILQ_INSERT_HEAD(&bz->bounce_page_list, bpage, links);
+ bz->free_bpages++;
+ bz->active_bpages--;
+ if ((map = STAILQ_FIRST(&bounce_map_waitinglist)) != NULL) {
+ if (reserve_bounce_pages(map->dmat, map, 1) == 0) {
+ STAILQ_REMOVE_HEAD(&bounce_map_waitinglist, links);
+ STAILQ_INSERT_TAIL(&bounce_map_callbacklist,
+ map, links);
+ busdma_swi_pending = 1;
+ bz->total_deferred++;
+ swi_sched(vm_ih, 0);
+ }
+ }
+ mtx_unlock(&bounce_lock);
+}
+
+void
+busdma_swi(void)
+{
+ bus_dma_tag_t dmat;
+ struct bus_dmamap *map;
+
+ mtx_lock(&bounce_lock);
+ while ((map = STAILQ_FIRST(&bounce_map_callbacklist)) != NULL) {
+ STAILQ_REMOVE_HEAD(&bounce_map_callbacklist, links);
+ mtx_unlock(&bounce_lock);
+ dmat = map->dmat;
+ (dmat->common.lockfunc)(dmat->common.lockfuncarg, BUS_DMA_LOCK);
+ bus_dmamap_load_mem(map->dmat, map, &map->mem,
+ map->callback, map->callback_arg, BUS_DMA_WAITOK);
+ (dmat->common.lockfunc)(dmat->common.lockfuncarg,
+ BUS_DMA_UNLOCK);
+ mtx_lock(&bounce_lock);
+ }
+ mtx_unlock(&bounce_lock);
+}
+
+struct bus_dma_impl bus_dma_bounce_impl = {
+ .tag_create = bounce_bus_dma_tag_create,
+ .tag_destroy = bounce_bus_dma_tag_destroy,
+ .map_create = bounce_bus_dmamap_create,
+ .map_destroy = bounce_bus_dmamap_destroy,
+ .mem_alloc = bounce_bus_dmamem_alloc,
+ .mem_free = bounce_bus_dmamem_free,
+ .load_phys = bounce_bus_dmamap_load_phys,
+ .load_buffer = bounce_bus_dmamap_load_buffer,
+ .load_ma = bus_dmamap_load_ma_triv,
+ .map_waitok = bounce_bus_dmamap_waitok,
+ .map_complete = bounce_bus_dmamap_complete,
+ .map_unload = bounce_bus_dmamap_unload,
+ .map_sync = bounce_bus_dmamap_sync
+};
diff --git a/sys/arm64/arm64/busdma_machdep.c b/sys/arm64/arm64/busdma_machdep.c
index 4a89b1f..df7a8be 100644
--- a/sys/arm64/arm64/busdma_machdep.c
+++ b/sys/arm64/arm64/busdma_machdep.c
@@ -1,22 +1,292 @@
-/* $FreeBSD$ */
+/*-
+ * Copyright (c) 1997, 1998 Justin T. Gibbs.
+ * Copyright (c) 2013, 2015 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Konstantin Belousov <kib@FreeBSD.org>
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * Portions of this software were developed by Semihalf
+ * under 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,
+ * without modification, immediately at the beginning of the file.
+ * 2. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
-
+#include <sys/malloc.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/lock.h>
+#include <sys/memdesc.h>
+#include <sys/mutex.h>
+#include <sys/uio.h>
#include <vm/vm.h>
+#include <vm/vm_extern.h>
#include <vm/pmap.h>
#include <machine/bus.h>
+#include <arm64/include/bus_dma_impl.h>
+
+/*
+ * Convenience function for manipulating driver locks from busdma (during
+ * busdma_swi, for example). Drivers that don't provide their own locks
+ * should specify &Giant to dmat->lockfuncarg. Drivers that use their own
+ * non-mutex locking scheme don't have to use this at all.
+ */
+void
+busdma_lock_mutex(void *arg, bus_dma_lock_op_t op)
+{
+ struct mtx *dmtx;
+
+ dmtx = (struct mtx *)arg;
+ switch (op) {
+ case BUS_DMA_LOCK:
+ mtx_lock(dmtx);
+ break;
+ case BUS_DMA_UNLOCK:
+ mtx_unlock(dmtx);
+ break;
+ default:
+ panic("Unknown operation 0x%x for busdma_lock_mutex!", op);
+ }
+}
+
+/*
+ * dflt_lock should never get called. It gets put into the dma tag when
+ * lockfunc == NULL, which is only valid if the maps that are associated
+ * with the tag are meant to never be defered.
+ * XXX Should have a way to identify which driver is responsible here.
+ */
+void
+bus_dma_dflt_lock(void *arg, bus_dma_lock_op_t op)
+{
+
+ panic("driver error: busdma dflt_lock called");
+}
+
+/*
+ * Return true if a match is made.
+ *
+ * To find a match walk the chain of bus_dma_tag_t's looking for 'paddr'.
+ *
+ * If paddr is within the bounds of the dma tag then call the filter callback
+ * to check for a match, if there is no filter callback then assume a match.
+ */
+int
+bus_dma_run_filter(struct bus_dma_tag_common *tc, bus_addr_t paddr)
+{
+ int retval;
+
+ retval = 0;
+ do {
+ if (((paddr > tc->lowaddr && paddr <= tc->highaddr) ||
+ ((paddr & (tc->alignment - 1)) != 0)) &&
+ (tc->filter == NULL ||
+ (*tc->filter)(tc->filterarg, paddr) != 0))
+ retval = 1;
+
+ tc = tc->parent;
+ } while (retval == 0 && tc != NULL);
+ return (retval);
+}
+
+int
+common_bus_dma_tag_create(struct bus_dma_tag_common *parent,
+ bus_size_t alignment, bus_addr_t boundary, bus_addr_t lowaddr,
+ bus_addr_t highaddr, bus_dma_filter_t *filter, void *filterarg,
+ bus_size_t maxsize, int nsegments, bus_size_t maxsegsz, int flags,
+ bus_dma_lock_t *lockfunc, void *lockfuncarg, size_t sz, void **dmat)
+{
+ void *newtag;
+ struct bus_dma_tag_common *common;
+
+ KASSERT(sz >= sizeof(struct bus_dma_tag_common), ("sz"));
+ /* Return a NULL tag on failure */
+ *dmat = NULL;
+ /* Basic sanity checking */
+ if (boundary != 0 && boundary < maxsegsz)
+ maxsegsz = boundary;
+ if (maxsegsz == 0)
+ return (EINVAL);
+
+ newtag = malloc(sz, M_DEVBUF, M_ZERO | M_NOWAIT);
+ if (newtag == NULL) {
+ CTR4(KTR_BUSDMA, "%s returned tag %p tag flags 0x%x error %d",
+ __func__, newtag, 0, ENOMEM);
+ return (ENOMEM);
+ }
+
+ common = newtag;
+ common->impl = &bus_dma_bounce_impl;
+ common->parent = parent;
+ common->alignment = alignment;
+ common->boundary = boundary;
+ common->lowaddr = trunc_page((vm_paddr_t)lowaddr) + (PAGE_SIZE - 1);
+ common->highaddr = trunc_page((vm_paddr_t)highaddr) + (PAGE_SIZE - 1);
+ common->filter = filter;
+ common->filterarg = filterarg;
+ common->maxsize = maxsize;
+ common->nsegments = nsegments;
+ common->maxsegsz = maxsegsz;
+ common->flags = flags;
+ common->ref_count = 1; /* Count ourself */
+ if (lockfunc != NULL) {
+ common->lockfunc = lockfunc;
+ common->lockfuncarg = lockfuncarg;
+ } else {
+ common->lockfunc = bus_dma_dflt_lock;
+ common->lockfuncarg = NULL;
+ }
+
+ /* Take into account any restrictions imposed by our parent tag */
+ if (parent != NULL) {
+ common->impl = parent->impl;
+ common->lowaddr = MIN(parent->lowaddr, common->lowaddr);
+ common->highaddr = MAX(parent->highaddr, common->highaddr);
+ if (common->boundary == 0)
+ common->boundary = parent->boundary;
+ else if (parent->boundary != 0) {
+ common->boundary = MIN(parent->boundary,
+ common->boundary);
+ }
+ if (common->filter == NULL) {
+ /*
+ * Short circuit looking at our parent directly
+ * since we have encapsulated all of its information
+ */
+ common->filter = parent->filter;
+ common->filterarg = parent->filterarg;
+ common->parent = parent->parent;
+ }
+ atomic_add_int(&parent->ref_count, 1);
+ }
+ *dmat = common;
+ return (0);
+}
+
+/*
+ * Allocate a device specific dma_tag.
+ */
+int
+bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment,
+ bus_addr_t boundary, bus_addr_t lowaddr, bus_addr_t highaddr,
+ bus_dma_filter_t *filter, void *filterarg, bus_size_t maxsize,
+ int nsegments, bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc,
+ void *lockfuncarg, bus_dma_tag_t *dmat)
+{
+ struct bus_dma_tag_common *tc;
+ int error;
+
+ if (parent == NULL) {
+ error = bus_dma_bounce_impl.tag_create(parent, alignment,
+ boundary, lowaddr, highaddr, filter, filterarg, maxsize,
+ nsegments, maxsegsz, flags, lockfunc, lockfuncarg, dmat);
+ } else {
+ tc = (struct bus_dma_tag_common *)parent;
+ error = tc->impl->tag_create(parent, alignment,
+ boundary, lowaddr, highaddr, filter, filterarg, maxsize,
+ nsegments, maxsegsz, flags, lockfunc, lockfuncarg, dmat);
+ }
+ return (error);
+}
+
+int
+bus_dma_tag_destroy(bus_dma_tag_t dmat)
+{
+ struct bus_dma_tag_common *tc;
+
+ tc = (struct bus_dma_tag_common *)dmat;
+ return (tc->impl->tag_destroy(dmat));
+}
+
+/*
+ * Allocate a handle for mapping from kva/uva/physical
+ * address space into bus device space.
+ */
+int
+bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp)
+{
+ struct bus_dma_tag_common *tc;
+
+ tc = (struct bus_dma_tag_common *)dmat;
+ return (tc->impl->map_create(dmat, flags, mapp));
+}
+
+/*
+ * Destroy a handle for mapping from kva/uva/physical
+ * address space into bus device space.
+ */
+int
+bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map)
+{
+ struct bus_dma_tag_common *tc;
+
+ tc = (struct bus_dma_tag_common *)dmat;
+ return (tc->impl->map_destroy(dmat, map));
+}
+
+
+/*
+ * Allocate a piece of memory that can be efficiently mapped into
+ * bus device space based on the constraints listed in the dma tag.
+ * A dmamap to for use with dmamap_load is also allocated.
+ */
+int
+bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
+ bus_dmamap_t *mapp)
+{
+ struct bus_dma_tag_common *tc;
+
+ tc = (struct bus_dma_tag_common *)dmat;
+ return (tc->impl->mem_alloc(dmat, vaddr, flags, mapp));
+}
+
+/*
+ * Free a piece of memory and it's allociated dmamap, that was allocated
+ * via bus_dmamem_alloc. Make the same choice for free/contigfree.
+ */
+void
+bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map)
+{
+ struct bus_dma_tag_common *tc;
+
+ tc = (struct bus_dma_tag_common *)dmat;
+ tc->impl->mem_free(dmat, vaddr, map);
+}
int
_bus_dmamap_load_phys(bus_dma_tag_t dmat, bus_dmamap_t map, vm_paddr_t buf,
bus_size_t buflen, int flags, bus_dma_segment_t *segs, int *segp)
{
+ struct bus_dma_tag_common *tc;
- panic("_bus_dmamap_load_phys");
+ tc = (struct bus_dma_tag_common *)dmat;
+ return (tc->impl->load_phys(dmat, map, buf, buflen, flags, segs,
+ segp));
}
int
@@ -24,8 +294,11 @@ _bus_dmamap_load_ma(bus_dma_tag_t dmat, bus_dmamap_t map, struct vm_page **ma,
bus_size_t tlen, int ma_offs, int flags, bus_dma_segment_t *segs,
int *segp)
{
+ struct bus_dma_tag_common *tc;
- panic("_bus_dmamap_load_ma");
+ tc = (struct bus_dma_tag_common *)dmat;
+ return (tc->impl->load_ma(dmat, map, ma, tlen, ma_offs, flags,
+ segs, segp));
}
int
@@ -33,36 +306,50 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
bus_size_t buflen, pmap_t pmap, int flags, bus_dma_segment_t *segs,
int *segp)
{
+ struct bus_dma_tag_common *tc;
- panic("_bus_dmamap_load_buffer");
+ tc = (struct bus_dma_tag_common *)dmat;
+ return (tc->impl->load_buffer(dmat, map, buf, buflen, pmap, flags, segs,
+ segp));
}
void
__bus_dmamap_waitok(bus_dma_tag_t dmat, bus_dmamap_t map,
struct memdesc *mem, bus_dmamap_callback_t *callback, void *callback_arg)
{
+ struct bus_dma_tag_common *tc;
- panic("__bus_dmamap_waitok");
+ tc = (struct bus_dma_tag_common *)dmat;
+ tc->impl->map_waitok(dmat, map, mem, callback, callback_arg);
}
bus_dma_segment_t *
_bus_dmamap_complete(bus_dma_tag_t dmat, bus_dmamap_t map,
bus_dma_segment_t *segs, int nsegs, int error)
{
+ struct bus_dma_tag_common *tc;
- panic("_bus_dmamap_complete");
+ tc = (struct bus_dma_tag_common *)dmat;
+ return (tc->impl->map_complete(dmat, map, segs, nsegs, error));
}
+/*
+ * Release the mapping held by map.
+ */
void
_bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map)
{
+ struct bus_dma_tag_common *tc;
- panic("_bus_dmamap_unload");
+ tc = (struct bus_dma_tag_common *)dmat;
+ tc->impl->map_unload(dmat, map);
}
void
_bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op)
{
+ struct bus_dma_tag_common *tc;
- panic("_bus_dmamap_sync");
+ tc = (struct bus_dma_tag_common *)dmat;
+ tc->impl->map_sync(dmat, map, op);
}
diff --git a/sys/arm64/include/bus_dma_impl.h b/sys/arm64/include/bus_dma_impl.h
new file mode 100644
index 0000000..354290e
--- /dev/null
+++ b/sys/arm64/include/bus_dma_impl.h
@@ -0,0 +1,96 @@
+/*-
+ * Copyright (c) 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Konstantin Belousov <kib@FreeBSD.org>
+ * under sponsorship from 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_BUS_DMA_IMPL_H_
+#define _MACHINE_BUS_DMA_IMPL_H_
+
+struct bus_dma_tag_common {
+ struct bus_dma_impl *impl;
+ struct bus_dma_tag_common *parent;
+ bus_size_t alignment;
+ bus_addr_t boundary;
+ bus_addr_t lowaddr;
+ bus_addr_t highaddr;
+ bus_dma_filter_t *filter;
+ void *filterarg;
+ bus_size_t maxsize;
+ u_int nsegments;
+ bus_size_t maxsegsz;
+ int flags;
+ bus_dma_lock_t *lockfunc;
+ void *lockfuncarg;
+ int ref_count;
+};
+
+struct bus_dma_impl {
+ int (*tag_create)(bus_dma_tag_t parent,
+ bus_size_t alignment, bus_addr_t boundary, bus_addr_t lowaddr,
+ bus_addr_t highaddr, bus_dma_filter_t *filter,
+ void *filterarg, bus_size_t maxsize, int nsegments,
+ bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc,
+ void *lockfuncarg, bus_dma_tag_t *dmat);
+ int (*tag_destroy)(bus_dma_tag_t dmat);
+ int (*map_create)(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp);
+ int (*map_destroy)(bus_dma_tag_t dmat, bus_dmamap_t map);
+ int (*mem_alloc)(bus_dma_tag_t dmat, void** vaddr, int flags,
+ bus_dmamap_t *mapp);
+ void (*mem_free)(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map);
+ int (*load_ma)(bus_dma_tag_t dmat, bus_dmamap_t map,
+ struct vm_page **ma, bus_size_t tlen, int ma_offs, int flags,
+ bus_dma_segment_t *segs, int *segp);
+ int (*load_phys)(bus_dma_tag_t dmat, bus_dmamap_t map,
+ vm_paddr_t buf, bus_size_t buflen, int flags,
+ bus_dma_segment_t *segs, int *segp);
+ int (*load_buffer)(bus_dma_tag_t dmat, bus_dmamap_t map,
+ void *buf, bus_size_t buflen, pmap_t pmap, int flags,
+ bus_dma_segment_t *segs, int *segp);
+ void (*map_waitok)(bus_dma_tag_t dmat, bus_dmamap_t map,
+ struct memdesc *mem, bus_dmamap_callback_t *callback,
+ void *callback_arg);
+ bus_dma_segment_t *(*map_complete)(bus_dma_tag_t dmat, bus_dmamap_t map,
+ bus_dma_segment_t *segs, int nsegs, int error);
+ void (*map_unload)(bus_dma_tag_t dmat, bus_dmamap_t map);
+ void (*map_sync)(bus_dma_tag_t dmat, bus_dmamap_t map,
+ bus_dmasync_op_t op);
+};
+
+void bus_dma_dflt_lock(void *arg, bus_dma_lock_op_t op);
+int bus_dma_run_filter(struct bus_dma_tag_common *dmat, bus_addr_t paddr);
+int common_bus_dma_tag_create(struct bus_dma_tag_common *parent,
+ bus_size_t alignment,
+ bus_addr_t boundary, bus_addr_t lowaddr, bus_addr_t highaddr,
+ bus_dma_filter_t *filter, void *filterarg, bus_size_t maxsize,
+ int nsegments, bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc,
+ void *lockfuncarg, size_t sz, void **dmat);
+
+extern struct bus_dma_impl bus_dma_bounce_impl;
+
+#endif
diff --git a/sys/boot/arm/uboot/ldscript.arm b/sys/boot/arm/uboot/ldscript.arm
index b3be119..1eb10a8 100644
--- a/sys/boot/arm/uboot/ldscript.arm
+++ b/sys/boot/arm/uboot/ldscript.arm
@@ -6,6 +6,15 @@ SECTIONS
{
/* Read-only sections, merged into text segment: */
. = UBLDR_LOADADDR + SIZEOF_HEADERS;
+ .text :
+ {
+ *(.text)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.gnu.linkonce.t*)
+ } =0
+ _etext = .;
+ PROVIDE (etext = .);
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
@@ -32,15 +41,6 @@ SECTIONS
.rela.sbss : { *(.rela.sbss) }
.rela.sdata2 : { *(.rela.sdata2) }
.rela.sbss2 : { *(.rela.sbss2) }
- .text :
- {
- *(.text)
- /* .gnu.warning sections are handled specially by elf32.em. */
- *(.gnu.warning)
- *(.gnu.linkonce.t*)
- } =0
- _etext = .;
- PROVIDE (etext = .);
.init : { *(.init) } =0
.fini : { *(.fini) } =0
.rodata : { *(.rodata) *(.gnu.linkonce.r*) }
diff --git a/sys/boot/fdt/dts/arm/odroidc1.dts b/sys/boot/fdt/dts/arm/odroidc1.dts
index c65344b..3079a9f 100644
--- a/sys/boot/fdt/dts/arm/odroidc1.dts
+++ b/sys/boot/fdt/dts/arm/odroidc1.dts
@@ -194,7 +194,6 @@
compatible = "amlogic,aml8726-rtc";
reg = <0xc8100740 20>; /* aobus 0x1d0 */
interrupts = <0 72 1>;
- interrupt-parent = <&gic>;
init-always = "false";
xo-init = <0x180a>;
@@ -246,7 +245,6 @@
compatible = "amlogic,aml8726-mmc";
reg = <0xc1108c20 32>; /* cbus 0x2308 */
interrupts = <0 28 1>;
- interrupt-parent = <&gic>;
clocks = <&clk81>;
@@ -274,7 +272,6 @@
clock-frequency = <1275000000>;
reg = <0xc1108e00 60>; /* cbus 0x2380 */
interrupts = <0 78 1>;
- interrupt-parent = <&gic>;
pinctrl-names = "default";
pinctrl-0 = <&pins_sdxc_c>;
@@ -311,7 +308,6 @@
compatible = "synopsys,designware-hs-otg2";
reg = <0xc9040000 0x40000>; /* ahbbus 0x40000*/
interrupts = <0 30 4>;
- interrupt-parent = <&gic>;
#address-cells = <1>;
#size-cells = <0>;
@@ -323,7 +319,6 @@
compatible = "synopsys,designware-hs-otg2";
reg = <0xc90c0000 0x40000>; /* ahbbus 0xc0000 */
interrupts = <0 31 4>;
- interrupt-parent = <&gic>;
#address-cells = <1>;
#size-cells = <0>;
@@ -335,7 +330,6 @@
compatible = "snps,dwmac";
reg = <0xc9410000 0x2000>; /* ahbbus 0x410000 */
interrupts = <0 8 1>;
- interrupt-parent = <&gic>;
#address-cells = <1>;
#size-cells = <0>;
@@ -352,7 +346,6 @@
<0 3 1>,
<0 12 1>,
<0 13 1>;
- interrupt-parent = <&gic>;
address = <0x7900000>; /* match memreserve */
width = <720>;
diff --git a/sys/boot/fdt/dts/arm/rpi2.dts b/sys/boot/fdt/dts/arm/rpi2.dts
index 1c8c559..e32cfb0 100644
--- a/sys/boot/fdt/dts/arm/rpi2.dts
+++ b/sys/boot/fdt/dts/arm/rpi2.dts
@@ -43,6 +43,24 @@
reg = <0xf00>; /* CPU ID=0xf00 */
clock-frequency = <800000000>; /* 800MHz */
};
+ cpu@1 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <0xf01>; /* CPU ID=0xf01 */
+ clock-frequency = <800000000>; /* 800MHz */
+ };
+ cpu@2 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <0xf02>; /* CPU ID=0xf02 */
+ clock-frequency = <800000000>; /* 800MHz */
+ };
+ cpu@3 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <0xf03>; /* CPU ID=0xf03 */
+ clock-frequency = <800000000>; /* 800MHz */
+ };
};
memory {
diff --git a/sys/boot/fdt/dts/arm/vsatv102-m6.dts b/sys/boot/fdt/dts/arm/vsatv102-m6.dts
index ad3b5a1..3ca8fc9 100644
--- a/sys/boot/fdt/dts/arm/vsatv102-m6.dts
+++ b/sys/boot/fdt/dts/arm/vsatv102-m6.dts
@@ -153,7 +153,6 @@
compatible = "amlogic,aml8726-rtc";
reg = <0xda004340 20>; /* secbus2 0xd0 */
interrupts = <0 72 1>; /* AM_IRQ2(8) */
- interrupt-parent = <&gic>;
init-always = "false";
xo-init = <0x180a>;
@@ -205,7 +204,6 @@
compatible = "amlogic,aml8726-mmc";
reg = <0xc1108c20 32>; /* cbus 0x2308 */
interrupts = <0 28 1>; /* AM_IRQ0(28) */
- interrupt-parent = <&gic>;
clocks = <&clk81>;
@@ -243,7 +241,6 @@
compatible = "synopsys,designware-hs-otg2";
reg = <0xc9040000 0x40000>; /* ahbbus 0x40000*/
interrupts = <0 30 4>; /* AM_IRQ0(30) */
- interrupt-parent = <&gic>;
#address-cells = <1>;
#size-cells = <0>;
};
@@ -253,7 +250,6 @@
compatible = "synopsys,designware-hs-otg2";
reg = <0xc90c0000 0x40000>; /* ahbbus 0xc0000 */
interrupts = <0 31 4>; /* AM_IRQ0(31) */
- interrupt-parent = <&gic>;
#address-cells = <1>;
#size-cells = <0>;
@@ -265,7 +261,6 @@
compatible = "snps,dwmac";
reg = <0xc9410000 0x2000>; /* ahbbus 0x410000 */
interrupts = <0 8 1>; /* AM_IRQ0(8) */
- interrupt-parent = <&gic>;
#address-cells = <1>;
#size-cells = <0>;
@@ -282,7 +277,6 @@
<0 3 1>, /* AM_IRQ0(3) */
<0 12 1>, /* AM_IRQ0(12) */
<0 13 1>; /* AM_IRQ0(13) */
- interrupt-parent = <&gic>;
address = <0x84900000>; /* match memreserve */
width = <720>;
diff --git a/sys/cam/ctl/ctl_backend_block.c b/sys/cam/ctl/ctl_backend_block.c
index a922967..b5582e9 100644
--- a/sys/cam/ctl/ctl_backend_block.c
+++ b/sys/cam/ctl/ctl_backend_block.c
@@ -521,7 +521,7 @@ ctl_be_block_biodone(struct bio *bio)
if (beio->num_errors > 0) {
if (error == EOPNOTSUPP) {
ctl_set_invalid_opcode(&io->scsiio);
- } else if (error == ENOSPC) {
+ } else if (error == ENOSPC || error == EDQUOT) {
ctl_set_space_alloc_fail(&io->scsiio);
} else if (beio->bio_cmd == BIO_FLUSH) {
/* XXX KDM is there is a better error here? */
@@ -738,7 +738,7 @@ ctl_be_block_dispatch_file(struct ctl_be_block_lun *be_lun,
ctl_scsi_path_string(io, path_str, sizeof(path_str));
printf("%s%s command returned errno %d\n", path_str,
(beio->bio_cmd == BIO_READ) ? "READ" : "WRITE", error);
- if (error == ENOSPC) {
+ if (error == ENOSPC || error == EDQUOT) {
ctl_set_space_alloc_fail(&io->scsiio);
} else
ctl_set_medium_error(&io->scsiio);
@@ -895,7 +895,7 @@ ctl_be_block_dispatch_zvol(struct ctl_be_block_lun *be_lun,
* return the I/O to the user.
*/
if (error != 0) {
- if (error == ENOSPC) {
+ if (error == ENOSPC || error == EDQUOT) {
ctl_set_space_alloc_fail(&io->scsiio);
} else
ctl_set_medium_error(&io->scsiio);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
index cbccad3..a0c1377 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
@@ -1142,7 +1142,8 @@ dmu_recv_begin_sync(void *arg, dmu_tx_t *tx)
}
dsobj = dsl_dataset_create_sync(ds->ds_dir, recv_clone_name,
snap, crflags, drba->drba_cred, tx);
- dsl_dataset_rele(snap, FTAG);
+ if (drba->drba_snapobj != 0)
+ dsl_dataset_rele(snap, FTAG);
dsl_dataset_rele(ds, FTAG);
} else {
dsl_dir_t *dd;
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index 06c8549..8f00f59 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -576,6 +576,7 @@ options STACK
# please see hwpmc(4).
device hwpmc # Driver (also a loadable module)
+options HWPMC_DEBUG
options HWPMC_HOOKS # Other necessary kernel hooks
diff --git a/sys/conf/files b/sys/conf/files
index caaed94..8d51fe5 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -4052,6 +4052,7 @@ xen/xenbus/xenbusb_if.m optional xenhvm
xen/xenbus/xenbusb.c optional xenhvm
xen/xenbus/xenbusb_front.c optional xenhvm
xen/xenbus/xenbusb_back.c optional xenhvm
+xen/xenmem/xenmem_if.m optional xenhvm
xdr/xdr.c optional krpc | nfslockd | nfscl | nfsd
xdr/xdr_array.c optional krpc | nfslockd | nfscl | nfsd
xdr/xdr_mbuf.c optional krpc | nfslockd | nfscl | nfsd
diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64
index f80fecd..9b1ff0d 100644
--- a/sys/conf/files.arm64
+++ b/sys/conf/files.arm64
@@ -5,6 +5,7 @@ arm64/arm64/autoconf.c standard
arm64/arm64/bcopy.c standard
arm64/arm64/bus_machdep.c standard
arm64/arm64/bus_space_asm.S standard
+arm64/arm64/busdma_bounce.c standard
arm64/arm64/busdma_machdep.c standard
arm64/arm64/clock.c standard
arm64/arm64/copyinout.S standard
diff --git a/sys/conf/options b/sys/conf/options
index 6d2a0fa..d7b937d 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -861,6 +861,7 @@ DCONS_FORCE_CONSOLE opt_dcons.h
DCONS_FORCE_GDB opt_dcons.h
# HWPMC options
+HWPMC_DEBUG opt_global.h
HWPMC_HOOKS
HWPMC_MIPS_BACKTRACE opt_hwpmc_hooks.h
diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
index 7796fbe..2176191 100644
--- a/sys/dev/acpica/acpi.c
+++ b/sys/dev/acpica/acpi.c
@@ -605,9 +605,11 @@ acpi_attach(device_t dev)
if (AcpiGbl_FADT.Flags & ACPI_FADT_RESET_REGISTER)
sc->acpi_handle_reboot = 1;
+#if !ACPI_REDUCED_HARDWARE
/* Only enable S4BIOS by default if the FACS says it is available. */
if (AcpiGbl_FACS != NULL && AcpiGbl_FACS->Flags & ACPI_FACS_S4_BIOS_PRESENT)
sc->acpi_s4bios = 1;
+#endif
/* Probe all supported sleep states. */
acpi_sleep_states[ACPI_STATE_S0] = TRUE;
diff --git a/sys/dev/acpica/acpi_cpu.c b/sys/dev/acpica/acpi_cpu.c
index 8df2782..a24ba4e 100644
--- a/sys/dev/acpica/acpi_cpu.c
+++ b/sys/dev/acpica/acpi_cpu.c
@@ -47,6 +47,8 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#if defined(__amd64__) || defined(__i386__)
#include <machine/clock.h>
+#include <machine/specialreg.h>
+#include <machine/md_var.h>
#endif
#include <sys/rman.h>
@@ -70,6 +72,10 @@ struct acpi_cx {
uint32_t power; /* Power consumed (mW). */
int res_type; /* Resource type for p_lvlx. */
int res_rid; /* Resource ID for p_lvlx. */
+ bool do_mwait;
+ uint32_t mwait_hint;
+ bool mwait_hw_coord;
+ bool mwait_bm_avoidance;
};
#define MAX_CX_STATES 8
@@ -128,6 +134,12 @@ struct acpi_cpu_device {
#define PIIX4_STOP_BREAK_MASK (PIIX4_BRLD_EN_IRQ0 | PIIX4_BRLD_EN_IRQ | PIIX4_BRLD_EN_IRQ8)
#define PIIX4_PCNTRL_BST_EN (1<<10)
+#define CST_FFH_VENDOR_INTEL 1
+#define CST_FFH_INTEL_CL_C1IO 1
+#define CST_FFH_INTEL_CL_MWAIT 2
+#define CST_FFH_MWAIT_HW_COORD 0x0001
+#define CST_FFH_MWAIT_BM_AVOID 0x0002
+
/* Allow users to ignore processor orders in MADT. */
static int cpu_unordered;
SYSCTL_INT(_debug_acpi, OID_AUTO, cpu_unordered, CTLFLAG_RDTUN,
@@ -179,6 +191,9 @@ static int acpi_cpu_usage_counters_sysctl(SYSCTL_HANDLER_ARGS);
static int acpi_cpu_set_cx_lowest(struct acpi_cpu_softc *sc);
static int acpi_cpu_cx_lowest_sysctl(SYSCTL_HANDLER_ARGS);
static int acpi_cpu_global_cx_lowest_sysctl(SYSCTL_HANDLER_ARGS);
+#if defined(__i386__) || defined(__amd64__)
+static int acpi_cpu_method_sysctl(SYSCTL_HANDLER_ARGS);
+#endif
static device_method_t acpi_cpu_methods[] = {
/* Device interface */
@@ -348,7 +363,18 @@ acpi_cpu_attach(device_t dev)
* so advertise this ourselves. Note this is not the same as independent
* SMP control where each CPU can have different settings.
*/
- sc->cpu_features = ACPI_CAP_SMP_SAME | ACPI_CAP_SMP_SAME_C3;
+ sc->cpu_features = ACPI_CAP_SMP_SAME | ACPI_CAP_SMP_SAME_C3 |
+ ACPI_CAP_C1_IO_HALT;
+
+#if defined(__i386__) || defined(__amd64__)
+ /*
+ * Ask for MWAIT modes if not disabled and interrupts work
+ * reasonable with MWAIT.
+ */
+ if (!acpi_disabled("mwait") && cpu_mwait_usable())
+ sc->cpu_features |= ACPI_CAP_SMP_C1_NATIVE | ACPI_CAP_SMP_C3_NATIVE;
+#endif
+
if (devclass_get_drivers(acpi_cpu_devclass, &drivers, &drv_count) == 0) {
for (i = 0; i < drv_count; i++) {
if (ACPI_GET_FEATURES(drivers[i], &features) == 0)
@@ -720,6 +746,27 @@ acpi_cpu_generic_cx_probe(struct acpi_cpu_softc *sc)
}
}
+static void
+acpi_cpu_cx_cst_mwait(struct acpi_cx *cx_ptr, uint64_t address, int accsize)
+{
+
+ cx_ptr->do_mwait = true;
+ cx_ptr->mwait_hint = address & 0xffffffff;
+ cx_ptr->mwait_hw_coord = (accsize & CST_FFH_MWAIT_HW_COORD) != 0;
+ cx_ptr->mwait_bm_avoidance = (accsize & CST_FFH_MWAIT_BM_AVOID) != 0;
+}
+
+static void
+acpi_cpu_cx_cst_free_plvlx(device_t cpu_dev, struct acpi_cx *cx_ptr)
+{
+
+ if (cx_ptr->p_lvlx == NULL)
+ return;
+ bus_release_resource(cpu_dev, cx_ptr->res_type, cx_ptr->res_rid,
+ cx_ptr->p_lvlx);
+ cx_ptr->p_lvlx = NULL;
+}
+
/*
* Parse a _CST package and set up its Cx states. Since the _CST object
* can change dynamically, our notify handler may call this function
@@ -734,7 +781,8 @@ acpi_cpu_cx_cst(struct acpi_cpu_softc *sc)
ACPI_OBJECT *top;
ACPI_OBJECT *pkg;
uint32_t count;
- int i;
+ uint64_t address;
+ int i, vendor, class, accsize;
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
@@ -790,6 +838,30 @@ acpi_cpu_cx_cst(struct acpi_cpu_softc *sc)
/* Validate the state to see if we should use it. */
switch (cx_ptr->type) {
case ACPI_STATE_C1:
+ acpi_cpu_cx_cst_free_plvlx(sc->cpu_dev, cx_ptr);
+#if defined(__i386__) || defined(__amd64__)
+ if (acpi_PkgFFH_IntelCpu(pkg, 0, &vendor, &class, &address,
+ &accsize) == 0 && vendor == CST_FFH_VENDOR_INTEL) {
+ if (class == CST_FFH_INTEL_CL_C1IO) {
+ /* C1 I/O then Halt */
+ cx_ptr->res_rid = sc->cpu_cx_count;
+ bus_set_resource(sc->cpu_dev, SYS_RES_IOPORT,
+ cx_ptr->res_rid, address, 1);
+ cx_ptr->p_lvlx = bus_alloc_resource_any(sc->cpu_dev,
+ SYS_RES_IOPORT, &cx_ptr->res_rid, RF_ACTIVE |
+ RF_SHAREABLE);
+ if (cx_ptr->p_lvlx == NULL) {
+ bus_delete_resource(sc->cpu_dev, SYS_RES_IOPORT,
+ cx_ptr->res_rid);
+ device_printf(sc->cpu_dev,
+ "C1 I/O failed to allocate port %d, "
+ "degrading to C1 Halt", (int)address);
+ }
+ } else if (class == CST_FFH_INTEL_CL_MWAIT) {
+ acpi_cpu_cx_cst_mwait(cx_ptr, address, accsize);
+ }
+ }
+#endif
if (sc->cpu_cx_states[0].type == ACPI_STATE_C0) {
/* This is the first C1 state. Use the reserved slot. */
sc->cpu_cx_states[0] = *cx_ptr;
@@ -818,23 +890,34 @@ acpi_cpu_cx_cst(struct acpi_cpu_softc *sc)
}
/* Free up any previous register. */
- if (cx_ptr->p_lvlx != NULL) {
- bus_release_resource(sc->cpu_dev, cx_ptr->res_type, cx_ptr->res_rid,
- cx_ptr->p_lvlx);
- cx_ptr->p_lvlx = NULL;
- }
+ acpi_cpu_cx_cst_free_plvlx(sc->cpu_dev, cx_ptr);
/* Allocate the control register for C2 or C3. */
- cx_ptr->res_rid = sc->cpu_cx_count;
- acpi_PkgGas(sc->cpu_dev, pkg, 0, &cx_ptr->res_type, &cx_ptr->res_rid,
- &cx_ptr->p_lvlx, RF_SHAREABLE);
- if (cx_ptr->p_lvlx) {
+#if defined(__i386__) || defined(__amd64__)
+ if (acpi_PkgFFH_IntelCpu(pkg, 0, &vendor, &class, &address,
+ &accsize) == 0 && vendor == CST_FFH_VENDOR_INTEL &&
+ class == CST_FFH_INTEL_CL_MWAIT) {
+ /* Native C State Instruction use (mwait) */
+ acpi_cpu_cx_cst_mwait(cx_ptr, address, accsize);
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "acpi_cpu%d: Got C%d - %d latency\n",
- device_get_unit(sc->cpu_dev), cx_ptr->type,
- cx_ptr->trans_lat));
+ "acpi_cpu%d: Got C%d/mwait - %d latency\n",
+ device_get_unit(sc->cpu_dev), cx_ptr->type, cx_ptr->trans_lat));
cx_ptr++;
sc->cpu_cx_count++;
+ } else
+#endif
+ {
+ cx_ptr->res_rid = sc->cpu_cx_count;
+ acpi_PkgGas(sc->cpu_dev, pkg, 0, &cx_ptr->res_type,
+ &cx_ptr->res_rid, &cx_ptr->p_lvlx, RF_SHAREABLE);
+ if (cx_ptr->p_lvlx) {
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "acpi_cpu%d: Got C%d - %d latency\n",
+ device_get_unit(sc->cpu_dev), cx_ptr->type,
+ cx_ptr->trans_lat));
+ cx_ptr++;
+ sc->cpu_cx_count++;
+ }
}
}
AcpiOsFree(buf.Pointer);
@@ -956,6 +1039,13 @@ acpi_cpu_startup_cx(struct acpi_cpu_softc *sc)
OID_AUTO, "cx_usage_counters", CTLTYPE_STRING | CTLFLAG_RD,
(void *)sc, 0, acpi_cpu_usage_counters_sysctl, "A",
"Cx sleep state counters");
+#if defined(__i386__) || defined(__amd64__)
+ SYSCTL_ADD_PROC(&sc->cpu_sysctl_ctx,
+ SYSCTL_CHILDREN(device_get_sysctl_tree(sc->cpu_dev)),
+ OID_AUTO, "cx_method", CTLTYPE_STRING | CTLFLAG_RD,
+ (void *)sc, 0, acpi_cpu_method_sysctl, "A",
+ "Cx entrance methods");
+#endif
/* Signal platform that we can handle _CST notification. */
if (!cpu_cx_generic && cpu_cst_cnt != 0) {
@@ -1043,7 +1133,14 @@ acpi_cpu_idle(sbintime_t sbt)
*/
if (cx_next->type == ACPI_STATE_C1) {
cputicks = cpu_ticks();
- acpi_cpu_c1();
+ if (cx_next->p_lvlx != NULL) {
+ /* C1 I/O then Halt */
+ CPU_GET_REG(cx_next->p_lvlx, 1);
+ }
+ if (cx_next->do_mwait)
+ acpi_cpu_idle_mwait(cx_next->mwait_hint);
+ else
+ acpi_cpu_c1();
end_time = ((cpu_ticks() - cputicks) << 20) / cpu_tickrate();
if (curthread->td_critnest == 0)
end_time = min(end_time, 500000 / hz);
@@ -1055,7 +1152,7 @@ acpi_cpu_idle(sbintime_t sbt)
* For C3, disable bus master arbitration and enable bus master wake
* if BM control is available, otherwise flush the CPU cache.
*/
- if (cx_next->type == ACPI_STATE_C3) {
+ if (cx_next->type == ACPI_STATE_C3 || cx_next->mwait_bm_avoidance) {
if ((cpu_quirks & CPU_QUIRK_NO_BM_CTRL) == 0) {
AcpiWriteBitRegister(ACPI_BITREG_ARB_DISABLE, 1);
AcpiWriteBitRegister(ACPI_BITREG_BUS_MASTER_RLD, 1);
@@ -1076,7 +1173,10 @@ acpi_cpu_idle(sbintime_t sbt)
start_time = 0;
cputicks = cpu_ticks();
}
- CPU_GET_REG(cx_next->p_lvlx, 1);
+ if (cx_next->do_mwait)
+ acpi_cpu_idle_mwait(cx_next->mwait_hint);
+ else
+ CPU_GET_REG(cx_next->p_lvlx, 1);
/*
* Read the end time twice. Since it may take an arbitrary time
@@ -1092,8 +1192,8 @@ acpi_cpu_idle(sbintime_t sbt)
end_time = ((cpu_ticks() - cputicks) << 20) / cpu_tickrate();
/* Enable bus master arbitration and disable bus master wakeup. */
- if (cx_next->type == ACPI_STATE_C3 &&
- (cpu_quirks & CPU_QUIRK_NO_BM_CTRL) == 0) {
+ if ((cx_next->type == ACPI_STATE_C3 || cx_next->mwait_bm_avoidance) &&
+ (cpu_quirks & CPU_QUIRK_NO_BM_CTRL) == 0) {
AcpiWriteBitRegister(ACPI_BITREG_ARB_DISABLE, 0);
AcpiWriteBitRegister(ACPI_BITREG_BUS_MASTER_RLD, 0);
}
@@ -1286,6 +1386,44 @@ acpi_cpu_usage_counters_sysctl(SYSCTL_HANDLER_ARGS)
return (0);
}
+#if defined(__i386__) || defined(__amd64__)
+static int
+acpi_cpu_method_sysctl(SYSCTL_HANDLER_ARGS)
+{
+ struct acpi_cpu_softc *sc;
+ struct acpi_cx *cx;
+ struct sbuf sb;
+ char buf[128];
+ int i;
+
+ sc = (struct acpi_cpu_softc *)arg1;
+ sbuf_new(&sb, buf, sizeof(buf), SBUF_FIXEDLEN);
+ for (i = 0; i < sc->cpu_cx_count; i++) {
+ cx = &sc->cpu_cx_states[i];
+ sbuf_printf(&sb, "C%d/", i + 1);
+ if (cx->do_mwait) {
+ sbuf_cat(&sb, "mwait");
+ if (cx->mwait_hw_coord)
+ sbuf_cat(&sb, "/hwc");
+ if (cx->mwait_bm_avoidance)
+ sbuf_cat(&sb, "/bma");
+ } else if (cx->type == ACPI_STATE_C1) {
+ sbuf_cat(&sb, "hlt");
+ } else {
+ sbuf_cat(&sb, "io");
+ }
+ if (cx->type == ACPI_STATE_C1 && cx->p_lvlx != NULL)
+ sbuf_cat(&sb, "/iohlt");
+ sbuf_putc(&sb, ' ');
+ }
+ sbuf_trim(&sb);
+ sbuf_finish(&sb);
+ sysctl_handle_string(oidp, sbuf_data(&sb), sbuf_len(&sb), req);
+ sbuf_delete(&sb);
+ return (0);
+}
+#endif
+
static int
acpi_cpu_set_cx_lowest(struct acpi_cpu_softc *sc)
{
diff --git a/sys/dev/acpica/acpi_package.c b/sys/dev/acpica/acpi_package.c
index e38fea5..c1070cb 100644
--- a/sys/dev/acpica/acpi_package.c
+++ b/sys/dev/acpica/acpi_package.c
@@ -120,6 +120,28 @@ acpi_PkgGas(device_t dev, ACPI_OBJECT *res, int idx, int *type, int *rid,
return (acpi_bus_alloc_gas(dev, type, rid, &gas, dst, flags));
}
+int
+acpi_PkgFFH_IntelCpu(ACPI_OBJECT *res, int idx, int *vendor, int *class,
+ uint64_t *address, int *accsize)
+{
+ ACPI_GENERIC_ADDRESS gas;
+ ACPI_OBJECT *obj;
+
+ obj = &res->Package.Elements[idx];
+ if (obj == NULL || obj->Type != ACPI_TYPE_BUFFER ||
+ obj->Buffer.Length < sizeof(ACPI_GENERIC_ADDRESS) + 3)
+ return (EINVAL);
+
+ memcpy(&gas, obj->Buffer.Pointer + 3, sizeof(gas));
+ if (gas.SpaceId != ACPI_ADR_SPACE_FIXED_HARDWARE)
+ return (ERESTART);
+ *vendor = gas.BitWidth;
+ *class = gas.BitOffset;
+ *address = gas.Address;
+ *accsize = gas.AccessWidth;
+ return (0);
+}
+
ACPI_HANDLE
acpi_GetReference(ACPI_HANDLE scope, ACPI_OBJECT *obj)
{
diff --git a/sys/dev/acpica/acpi_timer.c b/sys/dev/acpica/acpi_timer.c
index 03ef686..296e38f 100644
--- a/sys/dev/acpica/acpi_timer.c
+++ b/sys/dev/acpica/acpi_timer.c
@@ -128,7 +128,8 @@ acpi_timer_identify(driver_t *driver, device_t parent)
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
if (acpi_disabled("timer") || (acpi_quirks & ACPI_Q_TIMER) ||
- acpi_timer_dev || acpi_timer_disabled)
+ acpi_timer_dev || acpi_timer_disabled ||
+ AcpiGbl_FADT.PmTimerLength == 0)
return_VOID;
if ((dev = BUS_ADD_CHILD(parent, 2, "acpi_timer", 0)) == NULL) {
diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h
index 2e2b96d..cbd4bd9 100644
--- a/sys/dev/acpica/acpivar.h
+++ b/sys/dev/acpica/acpivar.h
@@ -467,6 +467,8 @@ int acpi_PkgInt32(ACPI_OBJECT *res, int idx, uint32_t *dst);
int acpi_PkgStr(ACPI_OBJECT *res, int idx, void *dst, size_t size);
int acpi_PkgGas(device_t dev, ACPI_OBJECT *res, int idx, int *type,
int *rid, struct resource **dst, u_int flags);
+int acpi_PkgFFH_IntelCpu(ACPI_OBJECT *res, int idx, int *vendor,
+ int *class, uint64_t *address, int *accsize);
ACPI_HANDLE acpi_GetReference(ACPI_HANDLE scope, ACPI_OBJECT *obj);
/*
diff --git a/sys/dev/hwpmc/hwpmc_amd.c b/sys/dev/hwpmc/hwpmc_amd.c
index 1a8398c..0bee138 100644
--- a/sys/dev/hwpmc/hwpmc_amd.c
+++ b/sys/dev/hwpmc/hwpmc_amd.c
@@ -47,7 +47,7 @@ __FBSDID("$FreeBSD$");
#include <machine/md_var.h>
#include <machine/specialreg.h>
-#ifdef DEBUG
+#ifdef HWPMC_DEBUG
enum pmc_class amd_pmc_class;
#endif
@@ -282,16 +282,16 @@ amd_read_pmc(int cpu, int ri, pmc_value_t *v)
mode = PMC_TO_MODE(pm);
- PMCDBG(MDP,REA,1,"amd-read id=%d class=%d", ri, pd->pm_descr.pd_class);
+ PMCDBG2(MDP,REA,1,"amd-read id=%d class=%d", ri, pd->pm_descr.pd_class);
-#ifdef DEBUG
+#ifdef HWPMC_DEBUG
KASSERT(pd->pm_descr.pd_class == amd_pmc_class,
("[amd,%d] unknown PMC class (%d)", __LINE__,
pd->pm_descr.pd_class));
#endif
tmp = rdmsr(pd->pm_perfctr); /* RDMSR serializes */
- PMCDBG(MDP,REA,2,"amd-read (pre-munge) id=%d -> %jd", ri, tmp);
+ PMCDBG2(MDP,REA,2,"amd-read (pre-munge) id=%d -> %jd", ri, tmp);
if (PMC_IS_SAMPLING_MODE(mode)) {
/* Sign extend 48 bit value to 64 bits. */
tmp = (pmc_value_t) (((int64_t) tmp << 16) >> 16);
@@ -299,7 +299,7 @@ amd_read_pmc(int cpu, int ri, pmc_value_t *v)
}
*v = tmp;
- PMCDBG(MDP,REA,2,"amd-read (post-munge) id=%d -> %jd", ri, *v);
+ PMCDBG2(MDP,REA,2,"amd-read (post-munge) id=%d -> %jd", ri, *v);
return 0;
}
@@ -329,7 +329,7 @@ amd_write_pmc(int cpu, int ri, pmc_value_t v)
mode = PMC_TO_MODE(pm);
-#ifdef DEBUG
+#ifdef HWPMC_DEBUG
KASSERT(pd->pm_descr.pd_class == amd_pmc_class,
("[amd,%d] unknown PMC class (%d)", __LINE__,
pd->pm_descr.pd_class));
@@ -339,7 +339,7 @@ amd_write_pmc(int cpu, int ri, pmc_value_t v)
if (PMC_IS_SAMPLING_MODE(mode))
v = AMD_RELOAD_COUNT_TO_PERFCTR_VALUE(v);
- PMCDBG(MDP,WRI,1,"amd-write cpu=%d ri=%d v=%jx", cpu, ri, v);
+ PMCDBG3(MDP,WRI,1,"amd-write cpu=%d ri=%d v=%jx", cpu, ri, v);
/* write the PMC value */
wrmsr(pd->pm_perfctr, v);
@@ -356,7 +356,7 @@ amd_config_pmc(int cpu, int ri, struct pmc *pm)
{
struct pmc_hw *phw;
- PMCDBG(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm);
+ PMCDBG3(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm);
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[amd,%d] illegal CPU value %d", __LINE__, cpu));
@@ -395,7 +395,7 @@ amd_switch_in(struct pmc_cpu *pc, struct pmc_process *pp)
{
(void) pc;
- PMCDBG(MDP,SWI,1, "pc=%p pp=%p enable-msr=%d", pc, pp,
+ PMCDBG3(MDP,SWI,1, "pc=%p pp=%p enable-msr=%d", pc, pp,
(pp->pp_flags & PMC_PP_ENABLE_MSR_ACCESS) != 0);
/* enable the RDPMC instruction if needed */
@@ -416,7 +416,7 @@ amd_switch_out(struct pmc_cpu *pc, struct pmc_process *pp)
(void) pc;
(void) pp; /* can be NULL */
- PMCDBG(MDP,SWO,1, "pc=%p pp=%p enable-msr=%d", pc, pp, pp ?
+ PMCDBG3(MDP,SWO,1, "pc=%p pp=%p enable-msr=%d", pc, pp, pp ?
(pp->pp_flags & PMC_PP_ENABLE_MSR_ACCESS) == 1 : 0);
/* always turn off the RDPMC instruction */
@@ -453,7 +453,7 @@ amd_allocate_pmc(int cpu, int ri, struct pmc *pm,
caps = pm->pm_caps;
- PMCDBG(MDP,ALL,1,"amd-allocate ri=%d caps=0x%x", ri, caps);
+ PMCDBG2(MDP,ALL,1,"amd-allocate ri=%d caps=0x%x", ri, caps);
if ((pd->pd_caps & caps) != caps)
return EPERM;
@@ -500,7 +500,7 @@ amd_allocate_pmc(int cpu, int ri, struct pmc *pm,
pm->pm_md.pm_amd.pm_amd_evsel = config; /* save config value */
- PMCDBG(MDP,ALL,2,"amd-allocate ri=%d -> config=0x%x", ri, config);
+ PMCDBG2(MDP,ALL,2,"amd-allocate ri=%d -> config=0x%x", ri, config);
return 0;
}
@@ -515,7 +515,7 @@ amd_allocate_pmc(int cpu, int ri, struct pmc *pm,
static int
amd_release_pmc(int cpu, int ri, struct pmc *pmc)
{
-#ifdef DEBUG
+#ifdef HWPMC_DEBUG
const struct amd_descr *pd;
#endif
struct pmc_hw *phw;
@@ -532,7 +532,7 @@ amd_release_pmc(int cpu, int ri, struct pmc *pmc)
KASSERT(phw->phw_pmc == NULL,
("[amd,%d] PHW pmc %p non-NULL", __LINE__, phw->phw_pmc));
-#ifdef DEBUG
+#ifdef HWPMC_DEBUG
pd = &amd_pmcdesc[ri];
if (pd->pm_descr.pd_class == amd_pmc_class)
KASSERT(AMD_PMC_IS_STOPPED(pd->pm_evsel),
@@ -567,7 +567,7 @@ amd_start_pmc(int cpu, int ri)
("[amd,%d] starting cpu%d,pmc%d with null pmc record", __LINE__,
cpu, ri));
- PMCDBG(MDP,STA,1,"amd-start cpu=%d ri=%d", cpu, ri);
+ PMCDBG2(MDP,STA,1,"amd-start cpu=%d ri=%d", cpu, ri);
KASSERT(AMD_PMC_IS_STOPPED(pd->pm_evsel),
("[amd,%d] pmc%d,cpu%d: Starting active PMC \"%s\"", __LINE__,
@@ -576,7 +576,7 @@ amd_start_pmc(int cpu, int ri)
/* turn on the PMC ENABLE bit */
config = pm->pm_md.pm_amd.pm_amd_evsel | AMD_PMC_ENABLE;
- PMCDBG(MDP,STA,2,"amd-start config=0x%x", config);
+ PMCDBG1(MDP,STA,2,"amd-start config=0x%x", config);
wrmsr(pd->pm_evsel, config);
return 0;
@@ -610,7 +610,7 @@ amd_stop_pmc(int cpu, int ri)
("[amd,%d] PMC%d, CPU%d \"%s\" already stopped",
__LINE__, ri, cpu, pd->pm_descr.pd_name));
- PMCDBG(MDP,STO,1,"amd-stop ri=%d", ri);
+ PMCDBG1(MDP,STO,1,"amd-stop ri=%d", ri);
/* turn off the PMC ENABLE bit */
config = pm->pm_md.pm_amd.pm_amd_evsel & ~AMD_PMC_ENABLE;
@@ -637,7 +637,7 @@ amd_intr(int cpu, struct trapframe *tf)
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[amd,%d] out of range CPU %d", __LINE__, cpu));
- PMCDBG(MDP,INT,1, "cpu=%d tf=%p um=%d", cpu, (void *) tf,
+ PMCDBG3(MDP,INT,1, "cpu=%d tf=%p um=%d", cpu, (void *) tf,
TRAPF_USERMODE(tf));
retval = 0;
@@ -769,7 +769,7 @@ amd_pcpu_init(struct pmc_mdep *md, int cpu)
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[amd,%d] insane cpu number %d", __LINE__, cpu));
- PMCDBG(MDP,INI,1,"amd-init cpu=%d", cpu);
+ PMCDBG1(MDP,INI,1,"amd-init cpu=%d", cpu);
amd_pcpu[cpu] = pac = malloc(sizeof(struct amd_cpu), M_PMC,
M_WAITOK|M_ZERO);
@@ -816,7 +816,7 @@ amd_pcpu_fini(struct pmc_mdep *md, int cpu)
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[amd,%d] insane cpu number (%d)", __LINE__, cpu));
- PMCDBG(MDP,INI,1,"amd-cleanup cpu=%d", cpu);
+ PMCDBG1(MDP,INI,1,"amd-cleanup cpu=%d", cpu);
/*
* First, turn off all PMCs on this CPU.
@@ -835,7 +835,7 @@ amd_pcpu_fini(struct pmc_mdep *md, int cpu)
amd_pcpu[cpu] = NULL;
-#ifdef DEBUG
+#ifdef HWPMC_DEBUG
for (i = 0; i < AMD_NPMCS; i++) {
KASSERT(pac->pc_amdpmcs[i].phw_pmc == NULL,
("[amd,%d] CPU%d/PMC%d in use", __LINE__, cpu, i));
@@ -912,7 +912,7 @@ pmc_amd_initialize(void)
return NULL;
}
-#ifdef DEBUG
+#ifdef HWPMC_DEBUG
amd_pmc_class = class;
#endif
@@ -976,7 +976,7 @@ pmc_amd_initialize(void)
pmc_mdep->pmd_npmc += AMD_NPMCS;
- PMCDBG(MDP,INI,0,"%s","amd-initialize");
+ PMCDBG0(MDP,INI,0,"amd-initialize");
return (pmc_mdep);
diff --git a/sys/dev/hwpmc/hwpmc_armv7.c b/sys/dev/hwpmc/hwpmc_armv7.c
index 13fdc76..66d4971 100644
--- a/sys/dev/hwpmc/hwpmc_armv7.c
+++ b/sys/dev/hwpmc/hwpmc_armv7.c
@@ -201,7 +201,7 @@ armv7_allocate_pmc(int cpu, int ri, struct pmc *pm,
pm->pm_md.pm_armv7.pm_armv7_evsel = config;
- PMCDBG(MDP,ALL,2,"armv7-allocate ri=%d -> config=0x%x", ri, config);
+ PMCDBG2(MDP,ALL,2,"armv7-allocate ri=%d -> config=0x%x", ri, config);
return 0;
}
@@ -225,7 +225,7 @@ armv7_read_pmc(int cpu, int ri, pmc_value_t *v)
else
tmp = armv7_pmcn_read(ri);
- PMCDBG(MDP,REA,2,"armv7-read id=%d -> %jd", ri, tmp);
+ PMCDBG2(MDP,REA,2,"armv7-read id=%d -> %jd", ri, tmp);
if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
*v = ARMV7_PERFCTR_VALUE_TO_RELOAD_COUNT(tmp);
else
@@ -249,7 +249,7 @@ armv7_write_pmc(int cpu, int ri, pmc_value_t v)
if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
v = ARMV7_RELOAD_COUNT_TO_PERFCTR_VALUE(v);
- PMCDBG(MDP,WRI,1,"armv7-write cpu=%d ri=%d v=%jx", cpu, ri, v);
+ PMCDBG3(MDP,WRI,1,"armv7-write cpu=%d ri=%d v=%jx", cpu, ri, v);
if (pm->pm_md.pm_armv7.pm_armv7_evsel == 0xFF)
cp15_pmccntr_set(v);
@@ -264,7 +264,7 @@ armv7_config_pmc(int cpu, int ri, struct pmc *pm)
{
struct pmc_hw *phw;
- PMCDBG(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm);
+ PMCDBG3(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm);
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[armv7,%d] illegal CPU value %d", __LINE__, cpu));
@@ -462,7 +462,7 @@ armv7_pcpu_init(struct pmc_mdep *md, int cpu)
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[armv7,%d] wrong cpu number %d", __LINE__, cpu));
- PMCDBG(MDP,INI,1,"armv7-init cpu=%d", cpu);
+ PMCDBG1(MDP,INI,1,"armv7-init cpu=%d", cpu);
armv7_pcpu[cpu] = pac = malloc(sizeof(struct armv7_cpu), M_PMC,
M_WAITOK|M_ZERO);
@@ -516,7 +516,7 @@ pmc_armv7_initialize()
armv7_npmcs = (reg >> ARMV7_PMNC_N_SHIFT) & \
ARMV7_PMNC_N_MASK;
- PMCDBG(MDP,INI,1,"armv7-init npmcs=%d", armv7_npmcs);
+ PMCDBG1(MDP,INI,1,"armv7-init npmcs=%d", armv7_npmcs);
/*
* Allocate space for pointers to PMC HW descriptors and for
diff --git a/sys/dev/hwpmc/hwpmc_core.c b/sys/dev/hwpmc/hwpmc_core.c
index f50dfb6c..afa5def 100644
--- a/sys/dev/hwpmc/hwpmc_core.c
+++ b/sys/dev/hwpmc/hwpmc_core.c
@@ -123,7 +123,7 @@ core_pcpu_init(struct pmc_mdep *md, int cpu)
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[iaf,%d] insane cpu number %d", __LINE__, cpu));
- PMCDBG(MDP,INI,1,"core-init cpu=%d", cpu);
+ PMCDBG1(MDP,INI,1,"core-init cpu=%d", cpu);
core_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_IAP].pcd_ri;
npmc = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_IAP].pcd_num;
@@ -162,7 +162,7 @@ core_pcpu_fini(struct pmc_mdep *md, int cpu)
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[core,%d] insane cpu number (%d)", __LINE__, cpu));
- PMCDBG(MDP,INI,1,"core-pcpu-fini cpu=%d", cpu);
+ PMCDBG1(MDP,INI,1,"core-pcpu-fini cpu=%d", cpu);
if ((cc = core_pcpu[cpu]) == NULL)
return (0);
@@ -223,7 +223,7 @@ iaf_allocate_pmc(int cpu, int ri, struct pmc *pm,
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[core,%d] illegal CPU %d", __LINE__, cpu));
- PMCDBG(MDP,ALL,1, "iaf-allocate ri=%d reqcaps=0x%x", ri, pm->pm_caps);
+ PMCDBG2(MDP,ALL,1, "iaf-allocate ri=%d reqcaps=0x%x", ri, pm->pm_caps);
if (ri < 0 || ri > core_iaf_npmc)
return (EINVAL);
@@ -267,7 +267,7 @@ iaf_allocate_pmc(int cpu, int ri, struct pmc *pm,
pm->pm_md.pm_iaf.pm_iaf_ctrl = (flags << (ri * 4));
- PMCDBG(MDP,ALL,2, "iaf-allocate config=0x%jx",
+ PMCDBG1(MDP,ALL,2, "iaf-allocate config=0x%jx",
(uintmax_t) pm->pm_md.pm_iaf.pm_iaf_ctrl);
return (0);
@@ -282,7 +282,7 @@ iaf_config_pmc(int cpu, int ri, struct pmc *pm)
KASSERT(ri >= 0 && ri < core_iaf_npmc,
("[core,%d] illegal row-index %d", __LINE__, ri));
- PMCDBG(MDP,CFG,1, "iaf-config cpu=%d ri=%d pm=%p", cpu, ri, pm);
+ PMCDBG3(MDP,CFG,1, "iaf-config cpu=%d ri=%d pm=%p", cpu, ri, pm);
KASSERT(core_pcpu[cpu] != NULL, ("[core,%d] null per-cpu %d", __LINE__,
cpu));
@@ -362,7 +362,7 @@ iaf_read_pmc(int cpu, int ri, pmc_value_t *v)
else
*v = tmp;
- PMCDBG(MDP,REA,1, "iaf-read cpu=%d ri=%d msr=0x%x -> v=%jx", cpu, ri,
+ PMCDBG4(MDP,REA,1, "iaf-read cpu=%d ri=%d msr=0x%x -> v=%jx", cpu, ri,
IAF_RI_TO_MSR(ri), *v);
return (0);
@@ -371,7 +371,7 @@ iaf_read_pmc(int cpu, int ri, pmc_value_t *v)
static int
iaf_release_pmc(int cpu, int ri, struct pmc *pmc)
{
- PMCDBG(MDP,REL,1, "iaf-release cpu=%d ri=%d pm=%p", cpu, ri, pmc);
+ PMCDBG3(MDP,REL,1, "iaf-release cpu=%d ri=%d pm=%p", cpu, ri, pmc);
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[core,%d] illegal CPU value %d", __LINE__, cpu));
@@ -396,7 +396,7 @@ iaf_start_pmc(int cpu, int ri)
KASSERT(ri >= 0 && ri < core_iaf_npmc,
("[core,%d] illegal row-index %d", __LINE__, ri));
- PMCDBG(MDP,STA,1,"iaf-start cpu=%d ri=%d", cpu, ri);
+ PMCDBG2(MDP,STA,1,"iaf-start cpu=%d ri=%d", cpu, ri);
iafc = core_pcpu[cpu];
pm = iafc->pc_corepmcs[ri + core_iaf_ri].phw_pmc;
@@ -414,7 +414,7 @@ iaf_start_pmc(int cpu, int ri)
IAF_GLOBAL_CTRL_MASK));
} while (iafc->pc_resync != 0);
- PMCDBG(MDP,STA,1,"iafctrl=%x(%x) globalctrl=%jx(%jx)",
+ PMCDBG4(MDP,STA,1,"iafctrl=%x(%x) globalctrl=%jx(%jx)",
iafc->pc_iafctrl, (uint32_t) rdmsr(IAF_CTRL),
iafc->pc_globalctrl, rdmsr(IA_GLOBAL_CTRL));
@@ -428,7 +428,7 @@ iaf_stop_pmc(int cpu, int ri)
struct core_cpu *iafc;
uint64_t msr = 0;
- PMCDBG(MDP,STO,1,"iaf-stop cpu=%d ri=%d", cpu, ri);
+ PMCDBG2(MDP,STO,1,"iaf-stop cpu=%d ri=%d", cpu, ri);
iafc = core_pcpu[cpu];
@@ -445,7 +445,7 @@ iaf_stop_pmc(int cpu, int ri)
iafc->pc_iafctrl &= ~fc;
- PMCDBG(MDP,STO,1,"iaf-stop iafctrl=%x", iafc->pc_iafctrl);
+ PMCDBG1(MDP,STO,1,"iaf-stop iafctrl=%x", iafc->pc_iafctrl);
msr = rdmsr(IAF_CTRL) & ~IAF_CTRL_MASK;
wrmsr(IAF_CTRL, msr | (iafc->pc_iafctrl & IAF_CTRL_MASK));
@@ -457,7 +457,7 @@ iaf_stop_pmc(int cpu, int ri)
IAF_GLOBAL_CTRL_MASK));
} while (iafc->pc_resync != 0);
- PMCDBG(MDP,STO,1,"iafctrl=%x(%x) globalctrl=%jx(%jx)",
+ PMCDBG4(MDP,STO,1,"iafctrl=%x(%x) globalctrl=%jx(%jx)",
iafc->pc_iafctrl, (uint32_t) rdmsr(IAF_CTRL),
iafc->pc_globalctrl, rdmsr(IA_GLOBAL_CTRL));
@@ -495,7 +495,7 @@ iaf_write_pmc(int cpu, int ri, pmc_value_t v)
msr = rdmsr(IAF_CTRL) & ~IAF_CTRL_MASK;
wrmsr(IAF_CTRL, msr | (cc->pc_iafctrl & IAF_CTRL_MASK));
- PMCDBG(MDP,WRI,1, "iaf-write cpu=%d ri=%d msr=0x%x v=%jx iafctrl=%jx "
+ PMCDBG6(MDP,WRI,1, "iaf-write cpu=%d ri=%d msr=0x%x v=%jx iafctrl=%jx "
"pmc=%jx", cpu, ri, IAF_RI_TO_MSR(ri), v,
(uintmax_t) rdmsr(IAF_CTRL),
(uintmax_t) rdpmc(IAF_RI_TO_MSR(ri)));
@@ -511,7 +511,7 @@ iaf_initialize(struct pmc_mdep *md, int maxcpu, int npmc, int pmcwidth)
KASSERT(md != NULL, ("[iaf,%d] md is NULL", __LINE__));
- PMCDBG(MDP,INI,1, "%s", "iaf-initialize");
+ PMCDBG0(MDP,INI,1, "iaf-initialize");
pcd = &md->pmd_classdep[PMC_MDEP_CLASS_INDEX_IAF];
@@ -2289,7 +2289,7 @@ iap_config_pmc(int cpu, int ri, struct pmc *pm)
KASSERT(ri >= 0 && ri < core_iap_npmc,
("[core,%d] illegal row-index %d", __LINE__, ri));
- PMCDBG(MDP,CFG,1, "iap-config cpu=%d ri=%d pm=%p", cpu, ri, pm);
+ PMCDBG3(MDP,CFG,1, "iap-config cpu=%d ri=%d pm=%p", cpu, ri, pm);
KASSERT(core_pcpu[cpu] != NULL, ("[core,%d] null per-cpu %d", __LINE__,
cpu));
@@ -2368,7 +2368,7 @@ iap_read_pmc(int cpu, int ri, pmc_value_t *v)
else
*v = tmp & ((1ULL << core_iap_width) - 1);
- PMCDBG(MDP,REA,1, "iap-read cpu=%d ri=%d msr=0x%x -> v=%jx", cpu, ri,
+ PMCDBG4(MDP,REA,1, "iap-read cpu=%d ri=%d msr=0x%x -> v=%jx", cpu, ri,
ri, *v);
return (0);
@@ -2379,7 +2379,7 @@ iap_release_pmc(int cpu, int ri, struct pmc *pm)
{
(void) pm;
- PMCDBG(MDP,REL,1, "iap-release cpu=%d ri=%d pm=%p", cpu, ri,
+ PMCDBG3(MDP,REL,1, "iap-release cpu=%d ri=%d pm=%p", cpu, ri,
pm);
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
@@ -2412,11 +2412,11 @@ iap_start_pmc(int cpu, int ri)
("[core,%d] starting cpu%d,ri%d with no pmc configured",
__LINE__, cpu, ri));
- PMCDBG(MDP,STA,1, "iap-start cpu=%d ri=%d", cpu, ri);
+ PMCDBG2(MDP,STA,1, "iap-start cpu=%d ri=%d", cpu, ri);
evsel = pm->pm_md.pm_iap.pm_iap_evsel;
- PMCDBG(MDP,STA,2, "iap-start/2 cpu=%d ri=%d evselmsr=0x%x evsel=0x%x",
+ PMCDBG4(MDP,STA,2, "iap-start/2 cpu=%d ri=%d evselmsr=0x%x evsel=0x%x",
cpu, ri, IAP_EVSEL0 + ri, evsel);
/* Event specific configuration. */
@@ -2464,7 +2464,7 @@ iap_stop_pmc(int cpu, int ri)
("[core,%d] cpu%d ri%d no configured PMC to stop", __LINE__,
cpu, ri));
- PMCDBG(MDP,STO,1, "iap-stop cpu=%d ri=%d", cpu, ri);
+ PMCDBG2(MDP,STO,1, "iap-stop cpu=%d ri=%d", cpu, ri);
msr = rdmsr(IAP_EVSEL0 + ri) & ~IAP_EVSEL_MASK;
wrmsr(IAP_EVSEL0 + ri, msr); /* stop hw */
@@ -2501,7 +2501,7 @@ iap_write_pmc(int cpu, int ri, pmc_value_t v)
("[core,%d] cpu%d ri%d no configured PMC to stop", __LINE__,
cpu, ri));
- PMCDBG(MDP,WRI,1, "iap-write cpu=%d ri=%d msr=0x%x v=%jx", cpu, ri,
+ PMCDBG4(MDP,WRI,1, "iap-write cpu=%d ri=%d msr=0x%x v=%jx", cpu, ri,
IAP_PMC0 + ri, v);
if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
@@ -2526,7 +2526,7 @@ iap_initialize(struct pmc_mdep *md, int maxcpu, int npmc, int pmcwidth,
KASSERT(md != NULL, ("[iap,%d] md is NULL", __LINE__));
- PMCDBG(MDP,INI,1, "%s", "iap-initialize");
+ PMCDBG0(MDP,INI,1, "iap-initialize");
/* Remember the set of architectural events supported. */
core_architectural_events = ~flags;
@@ -2564,7 +2564,7 @@ core_intr(int cpu, struct trapframe *tf)
int error, found_interrupt, ri;
uint64_t msr;
- PMCDBG(MDP,INT, 1, "cpu=%d tf=0x%p um=%d", cpu, (void *) tf,
+ PMCDBG3(MDP,INT, 1, "cpu=%d tf=0x%p um=%d", cpu, (void *) tf,
TRAPF_USERMODE(tf));
found_interrupt = 0;
@@ -2623,7 +2623,7 @@ core2_intr(int cpu, struct trapframe *tf)
struct core_cpu *cc;
pmc_value_t v;
- PMCDBG(MDP,INT, 1, "cpu=%d tf=0x%p um=%d", cpu, (void *) tf,
+ PMCDBG3(MDP,INT, 1, "cpu=%d tf=0x%p um=%d", cpu, (void *) tf,
TRAPF_USERMODE(tf));
/*
@@ -2635,7 +2635,7 @@ core2_intr(int cpu, struct trapframe *tf)
intrstatus = rdmsr(IA_GLOBAL_STATUS);
intrenable = intrstatus & core_pmcmask;
- PMCDBG(MDP,INT, 1, "cpu=%d intrstatus=%jx", cpu,
+ PMCDBG2(MDP,INT, 1, "cpu=%d intrstatus=%jx", cpu,
(uintmax_t) intrstatus);
found_interrupt = 0;
@@ -2681,7 +2681,7 @@ core2_intr(int cpu, struct trapframe *tf)
/* Reload sampling count. */
wrmsr(IAF_CTR0 + n, v);
- PMCDBG(MDP,INT, 1, "iaf-intr cpu=%d error=%d v=%jx(%jx)", cpu,
+ PMCDBG4(MDP,INT, 1, "iaf-intr cpu=%d error=%d v=%jx(%jx)", cpu,
error, (uintmax_t) v, (uintmax_t) rdpmc(IAF_RI_TO_MSR(n)));
}
@@ -2706,7 +2706,7 @@ core2_intr(int cpu, struct trapframe *tf)
v = iap_reload_count_to_perfctr_value(pm->pm_sc.pm_reloadcount);
- PMCDBG(MDP,INT, 1, "iap-intr cpu=%d error=%d v=%jx", cpu, error,
+ PMCDBG3(MDP,INT, 1, "iap-intr cpu=%d error=%d v=%jx", cpu, error,
(uintmax_t) v);
/* Reload sampling count. */
@@ -2716,14 +2716,14 @@ core2_intr(int cpu, struct trapframe *tf)
/*
* Reenable all non-stalled PMCs.
*/
- PMCDBG(MDP,INT, 1, "cpu=%d intrenable=%jx", cpu,
+ PMCDBG2(MDP,INT, 1, "cpu=%d intrenable=%jx", cpu,
(uintmax_t) intrenable);
cc->pc_globalctrl |= intrenable;
wrmsr(IA_GLOBAL_CTRL, cc->pc_globalctrl & IA_GLOBAL_CTRL_MASK);
- PMCDBG(MDP,INT, 1, "cpu=%d fixedctrl=%jx globalctrl=%jx status=%jx "
+ PMCDBG5(MDP,INT, 1, "cpu=%d fixedctrl=%jx globalctrl=%jx status=%jx "
"ovf=%jx", cpu, (uintmax_t) rdmsr(IAF_CTRL),
(uintmax_t) rdmsr(IA_GLOBAL_CTRL),
(uintmax_t) rdmsr(IA_GLOBAL_STATUS),
@@ -2750,7 +2750,7 @@ pmc_core_initialize(struct pmc_mdep *md, int maxcpu, int version_override)
cpuid[CORE_CPUID_EAX] & 0xFF;
core_cputype = md->pmd_cputype;
- PMCDBG(MDP,INI,1,"core-init cputype=%d ncpu=%d ipa-version=%d",
+ PMCDBG3(MDP,INI,1,"core-init cputype=%d ncpu=%d ipa-version=%d",
core_cputype, maxcpu, ipa_version);
if (ipa_version < 1 || ipa_version > 3 ||
@@ -2788,7 +2788,7 @@ pmc_core_initialize(struct pmc_mdep *md, int maxcpu, int version_override)
core_pmcmask |= ((1ULL << core_iaf_npmc) - 1) << IAF_OFFSET;
}
- PMCDBG(MDP,INI,1,"core-init pmcmask=0x%jx iafri=%d", core_pmcmask,
+ PMCDBG2(MDP,INI,1,"core-init pmcmask=0x%jx iafri=%d", core_pmcmask,
core_iaf_ri);
core_pcpu = malloc(sizeof(*core_pcpu) * maxcpu, M_PMC,
@@ -2811,7 +2811,7 @@ pmc_core_initialize(struct pmc_mdep *md, int maxcpu, int version_override)
void
pmc_core_finalize(struct pmc_mdep *md)
{
- PMCDBG(MDP,INI,1, "%s", "core-finalize");
+ PMCDBG0(MDP,INI,1, "core-finalize");
free(core_pcpu, M_PMC);
core_pcpu = NULL;
diff --git a/sys/dev/hwpmc/hwpmc_e500.c b/sys/dev/hwpmc/hwpmc_e500.c
index d81b333..d963e73 100644
--- a/sys/dev/hwpmc/hwpmc_e500.c
+++ b/sys/dev/hwpmc/hwpmc_e500.c
@@ -304,7 +304,7 @@ e500_read_pmc(int cpu, int ri, pmc_value_t *v)
ri));
tmp = e500_pmcn_read(ri);
- PMCDBG(MDP,REA,2,"ppc-read id=%d -> %jd", ri, tmp);
+ PMCDBG2(MDP,REA,2,"ppc-read id=%d -> %jd", ri, tmp);
if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
*v = POWERPC_PERFCTR_VALUE_TO_RELOAD_COUNT(tmp);
else
@@ -328,7 +328,7 @@ e500_write_pmc(int cpu, int ri, pmc_value_t v)
if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
v = POWERPC_RELOAD_COUNT_TO_PERFCTR_VALUE(v);
- PMCDBG(MDP,WRI,1,"powerpc-write cpu=%d ri=%d v=%jx", cpu, ri, v);
+ PMCDBG3(MDP,WRI,1,"powerpc-write cpu=%d ri=%d v=%jx", cpu, ri, v);
e500_pmcn_write(ri, v);
@@ -340,7 +340,7 @@ e500_config_pmc(int cpu, int ri, struct pmc *pm)
{
struct pmc_hw *phw;
- PMCDBG(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm);
+ PMCDBG3(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm);
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[powerpc,%d] illegal CPU value %d", __LINE__, cpu));
@@ -443,7 +443,7 @@ e500_pcpu_init(struct pmc_mdep *md, int cpu)
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[powerpc,%d] wrong cpu number %d", __LINE__, cpu));
- PMCDBG(MDP,INI,1,"powerpc-init cpu=%d", cpu);
+ PMCDBG1(MDP,INI,1,"powerpc-init cpu=%d", cpu);
/* Freeze all counters. */
mtpmr(PMR_PMGC0, PMGC_FAC | PMGC_PMIE | PMGC_FCECE);
@@ -543,7 +543,7 @@ e500_allocate_pmc(int cpu, int ri, struct pmc *pm,
pm->pm_md.pm_powerpc.pm_powerpc_evsel = config;
- PMCDBG(MDP,ALL,2,"powerpc-allocate ri=%d -> config=0x%x", ri, config);
+ PMCDBG2(MDP,ALL,2,"powerpc-allocate ri=%d -> config=0x%x", ri, config);
return 0;
}
@@ -576,7 +576,7 @@ e500_intr(int cpu, struct trapframe *tf)
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[powerpc,%d] out of range CPU %d", __LINE__, cpu));
- PMCDBG(MDP,INT,1, "cpu=%d tf=%p um=%d", cpu, (void *) tf,
+ PMCDBG3(MDP,INT,1, "cpu=%d tf=%p um=%d", cpu, (void *) tf,
TRAPF_USERMODE(tf));
retval = 0;
diff --git a/sys/dev/hwpmc/hwpmc_intel.c b/sys/dev/hwpmc/hwpmc_intel.c
index 486dfa0..ce49f54 100644
--- a/sys/dev/hwpmc/hwpmc_intel.c
+++ b/sys/dev/hwpmc/hwpmc_intel.c
@@ -46,14 +46,14 @@ intel_switch_in(struct pmc_cpu *pc, struct pmc_process *pp)
{
(void) pc;
- PMCDBG(MDP,SWI,1, "pc=%p pp=%p enable-msr=%d", pc, pp,
+ PMCDBG3(MDP,SWI,1, "pc=%p pp=%p enable-msr=%d", pc, pp,
pp->pp_flags & PMC_PP_ENABLE_MSR_ACCESS);
/* allow the RDPMC instruction if needed */
if (pp->pp_flags & PMC_PP_ENABLE_MSR_ACCESS)
load_cr4(rcr4() | CR4_PCE);
- PMCDBG(MDP,SWI,1, "cr4=0x%jx", (uintmax_t) rcr4());
+ PMCDBG1(MDP,SWI,1, "cr4=0x%jx", (uintmax_t) rcr4());
return 0;
}
@@ -64,7 +64,7 @@ intel_switch_out(struct pmc_cpu *pc, struct pmc_process *pp)
(void) pc;
(void) pp; /* can be NULL */
- PMCDBG(MDP,SWO,1, "pc=%p pp=%p cr4=0x%jx", pc, pp,
+ PMCDBG3(MDP,SWO,1, "pc=%p pp=%p cr4=0x%jx", pc, pp,
(uintmax_t) rcr4());
/* always turn off the RDPMC instruction */
@@ -83,7 +83,7 @@ pmc_intel_initialize(void)
KASSERT(cpu_vendor_id == CPU_VENDOR_INTEL,
("[intel,%d] Initializing non-intel processor", __LINE__));
- PMCDBG(MDP,INI,0, "intel-initialize cpuid=0x%x", cpu_id);
+ PMCDBG1(MDP,INI,0, "intel-initialize cpuid=0x%x", cpu_id);
cputype = -1;
nclasses = 2;
diff --git a/sys/dev/hwpmc/hwpmc_logging.c b/sys/dev/hwpmc/hwpmc_logging.c
index 4d14011..cc85481 100644
--- a/sys/dev/hwpmc/hwpmc_logging.c
+++ b/sys/dev/hwpmc/hwpmc_logging.c
@@ -211,9 +211,9 @@ pmclog_get_buffer(struct pmc_owner *po)
TAILQ_REMOVE(&pmc_bufferlist, plb, plb_next);
mtx_unlock_spin(&pmc_bufferlist_mtx);
- PMCDBG(LOG,GTB,1, "po=%p plb=%p", po, plb);
+ PMCDBG2(LOG,GTB,1, "po=%p plb=%p", po, plb);
-#ifdef DEBUG
+#ifdef HWPMC_DEBUG
if (plb)
KASSERT(plb->plb_ptr == plb->plb_base &&
plb->plb_base < plb->plb_fence,
@@ -261,7 +261,7 @@ pmclog_loop(void *arg)
ownercred = crhold(p->p_ucred);
PROC_UNLOCK(p);
- PMCDBG(LOG,INI,1, "po=%p kt=%p", po, po->po_kthread);
+ PMCDBG2(LOG,INI,1, "po=%p kt=%p", po, po->po_kthread);
KASSERT(po->po_kthread == curthread->td_proc,
("[pmclog,%d] proc mismatch po=%p po/kt=%p curproc=%p", __LINE__,
po, po->po_kthread, curthread->td_proc));
@@ -312,7 +312,7 @@ pmclog_loop(void *arg)
mtx_unlock(&pmc_kthread_mtx);
/* process the request */
- PMCDBG(LOG,WRI,2, "po=%p base=%p ptr=%p", po,
+ PMCDBG3(LOG,WRI,2, "po=%p base=%p ptr=%p", po,
lb->plb_base, lb->plb_ptr);
/* change our thread's credentials before issuing the I/O */
@@ -343,7 +343,7 @@ pmclog_loop(void *arg)
po->po_error = error; /* save for flush log */
- PMCDBG(LOG,WRI,2, "po=%p error=%d", po, error);
+ PMCDBG2(LOG,WRI,2, "po=%p error=%d", po, error);
break;
}
@@ -403,7 +403,7 @@ pmclog_release(struct pmc_owner *po)
mtx_unlock_spin(&po->po_mtx);
- PMCDBG(LOG,REL,1, "po=%p", po);
+ PMCDBG1(LOG,REL,1, "po=%p", po);
}
@@ -423,7 +423,7 @@ pmclog_reserve(struct pmc_owner *po, int length)
uint32_t *lh;
struct timespec ts;
- PMCDBG(LOG,ALL,1, "po=%p len=%d", po, length);
+ PMCDBG2(LOG,ALL,1, "po=%p len=%d", po, length);
KASSERT(length % sizeof(uint32_t) == 0,
("[pmclog,%d] length not a multiple of word size", __LINE__));
@@ -519,7 +519,7 @@ pmclog_schedule_io(struct pmc_owner *po)
("[pmclog,%d] buffer invariants po=%p ptr=%p fenc=%p", __LINE__,
po, po->po_curbuf->plb_ptr, po->po_curbuf->plb_fence));
- PMCDBG(LOG,SIO, 1, "po=%p", po);
+ PMCDBG1(LOG,SIO, 1, "po=%p", po);
mtx_assert(&po->po_mtx, MA_OWNED);
@@ -579,7 +579,7 @@ pmclog_configure_log(struct pmc_mdep *md, struct pmc_owner *po, int logfd)
* the former is not held here.
*/
sx_assert(&pmc_sx, SA_UNLOCKED);
- PMCDBG(LOG,CFG,1, "config po=%p logfd=%d", po, logfd);
+ PMCDBG2(LOG,CFG,1, "config po=%p logfd=%d", po, logfd);
p = po->po_owner;
@@ -649,7 +649,7 @@ pmclog_deconfigure_log(struct pmc_owner *po)
int error;
struct pmclog_buffer *lb;
- PMCDBG(LOG,CFG,1, "de-config po=%p", po);
+ PMCDBG1(LOG,CFG,1, "de-config po=%p", po);
if ((po->po_flags & PMC_PO_OWNS_LOGFILE) == 0)
return (EINVAL);
@@ -700,7 +700,7 @@ pmclog_flush(struct pmc_owner *po)
int error;
struct pmclog_buffer *lb;
- PMCDBG(LOG,FLS,1, "po=%p", po);
+ PMCDBG1(LOG,FLS,1, "po=%p", po);
/*
* If there is a pending error recorded by the logger thread,
@@ -741,7 +741,7 @@ int
pmclog_close(struct pmc_owner *po)
{
- PMCDBG(LOG,CLO,1, "po=%p", po);
+ PMCDBG1(LOG,CLO,1, "po=%p", po);
mtx_lock(&pmc_kthread_mtx);
@@ -773,7 +773,7 @@ pmclog_process_callchain(struct pmc *pm, struct pmc_sample *ps)
uint32_t flags;
struct pmc_owner *po;
- PMCDBG(LOG,SAM,1,"pm=%p pid=%d n=%d", pm, ps->ps_pid,
+ PMCDBG3(LOG,SAM,1,"pm=%p pid=%d n=%d", pm, ps->ps_pid,
ps->ps_nsamples);
recordlen = offsetof(struct pmclog_callchain, pl_pc) +
@@ -843,7 +843,7 @@ pmclog_process_pmcallocate(struct pmc *pm)
po = pm->pm_owner;
- PMCDBG(LOG,ALL,1, "pm=%p", pm);
+ PMCDBG1(LOG,ALL,1, "pm=%p", pm);
if (PMC_TO_CLASS(pm) == PMC_CLASS_SOFT) {
PMCLOG_RESERVE(po, PMCALLOCATEDYN,
@@ -874,7 +874,7 @@ pmclog_process_pmcattach(struct pmc *pm, pid_t pid, char *path)
int pathlen, recordlen;
struct pmc_owner *po;
- PMCDBG(LOG,ATT,1,"pm=%p pid=%d", pm, pid);
+ PMCDBG2(LOG,ATT,1,"pm=%p pid=%d", pm, pid);
po = pm->pm_owner;
@@ -893,7 +893,7 @@ pmclog_process_pmcdetach(struct pmc *pm, pid_t pid)
{
struct pmc_owner *po;
- PMCDBG(LOG,ATT,1,"!pm=%p pid=%d", pm, pid);
+ PMCDBG2(LOG,ATT,1,"!pm=%p pid=%d", pm, pid);
po = pm->pm_owner;
@@ -915,7 +915,7 @@ pmclog_process_proccsw(struct pmc *pm, struct pmc_process *pp, pmc_value_t v)
KASSERT(pm->pm_flags & PMC_F_LOG_PROCCSW,
("[pmclog,%d] log-process-csw called gratuitously", __LINE__));
- PMCDBG(LOG,SWO,1,"pm=%p pid=%d v=%jx", pm, pp->pp_proc->p_pid,
+ PMCDBG3(LOG,SWO,1,"pm=%p pid=%d v=%jx", pm, pp->pp_proc->p_pid,
v);
po = pm->pm_owner;
@@ -933,7 +933,7 @@ pmclog_process_procexec(struct pmc_owner *po, pmc_id_t pmid, pid_t pid,
{
int pathlen, recordlen;
- PMCDBG(LOG,EXC,1,"po=%p pid=%d path=\"%s\"", po, pid, path);
+ PMCDBG3(LOG,EXC,1,"po=%p pid=%d path=\"%s\"", po, pid, path);
pathlen = strlen(path) + 1; /* #bytes for the path */
recordlen = offsetof(struct pmclog_procexec, pl_pathname) + pathlen;
@@ -957,7 +957,7 @@ pmclog_process_procexit(struct pmc *pm, struct pmc_process *pp)
struct pmc_owner *po;
ri = PMC_TO_ROWINDEX(pm);
- PMCDBG(LOG,EXT,1,"pm=%p pid=%d v=%jx", pm, pp->pp_proc->p_pid,
+ PMCDBG3(LOG,EXT,1,"pm=%p pid=%d v=%jx", pm, pp->pp_proc->p_pid,
pp->pp_pmcs[ri].pp_pmcval);
po = pm->pm_owner;
@@ -1003,7 +1003,7 @@ pmclog_process_userlog(struct pmc_owner *po, struct pmc_op_writelog *wl)
{
int error;
- PMCDBG(LOG,WRI,1, "writelog po=%p ud=0x%x", po, wl->pm_userdata);
+ PMCDBG2(LOG,WRI,1, "writelog po=%p ud=0x%x", po, wl->pm_userdata);
error = 0;
diff --git a/sys/dev/hwpmc/hwpmc_mips.c b/sys/dev/hwpmc/hwpmc_mips.c
index 68a81e0..72f8e89 100644
--- a/sys/dev/hwpmc/hwpmc_mips.c
+++ b/sys/dev/hwpmc/hwpmc_mips.c
@@ -104,7 +104,7 @@ mips_allocate_pmc(int cpu, int ri, struct pmc *pm,
pm->pm_md.pm_mips_evsel = config;
- PMCDBG(MDP,ALL,2,"mips-allocate ri=%d -> config=0x%x", ri, config);
+ PMCDBG2(MDP,ALL,2,"mips-allocate ri=%d -> config=0x%x", ri, config);
return 0;
}
@@ -123,7 +123,7 @@ mips_read_pmc(int cpu, int ri, pmc_value_t *v)
pm = mips_pcpu[cpu]->pc_mipspmcs[ri].phw_pmc;
tmp = mips_pmcn_read(ri);
- PMCDBG(MDP,REA,2,"mips-read id=%d -> %jd", ri, tmp);
+ PMCDBG2(MDP,REA,2,"mips-read id=%d -> %jd", ri, tmp);
if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
*v = tmp - (1UL << (mips_pmc_spec.ps_counter_width - 1));
@@ -148,7 +148,7 @@ mips_write_pmc(int cpu, int ri, pmc_value_t v)
if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
v = (1UL << (mips_pmc_spec.ps_counter_width - 1)) - v;
- PMCDBG(MDP,WRI,1,"mips-write cpu=%d ri=%d v=%jx", cpu, ri, v);
+ PMCDBG3(MDP,WRI,1,"mips-write cpu=%d ri=%d v=%jx", cpu, ri, v);
mips_pmcn_write(ri, v);
@@ -160,7 +160,7 @@ mips_config_pmc(int cpu, int ri, struct pmc *pm)
{
struct pmc_hw *phw;
- PMCDBG(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm);
+ PMCDBG3(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm);
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[mips,%d] illegal CPU value %d", __LINE__, cpu));
@@ -376,7 +376,7 @@ mips_pcpu_init(struct pmc_mdep *md, int cpu)
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[mips,%d] wrong cpu number %d", __LINE__, cpu));
- PMCDBG(MDP,INI,1,"mips-init cpu=%d", cpu);
+ PMCDBG1(MDP,INI,1,"mips-init cpu=%d", cpu);
mips_pcpu[cpu] = pac = malloc(sizeof(struct mips_cpu), M_PMC,
M_WAITOK|M_ZERO);
@@ -421,7 +421,7 @@ pmc_mips_initialize()
*/
mips_npmcs = 2;
- PMCDBG(MDP,INI,1,"mips-init npmcs=%d", mips_npmcs);
+ PMCDBG1(MDP,INI,1,"mips-init npmcs=%d", mips_npmcs);
/*
* Allocate space for pointers to PMC HW descriptors and for
diff --git a/sys/dev/hwpmc/hwpmc_mips24k.c b/sys/dev/hwpmc/hwpmc_mips24k.c
index 18d7f6c..7841555 100644
--- a/sys/dev/hwpmc/hwpmc_mips24k.c
+++ b/sys/dev/hwpmc/hwpmc_mips24k.c
@@ -223,7 +223,7 @@ mips_get_perfctl(int cpu, int ri, uint32_t event, uint32_t caps)
if (caps & PMC_CAP_INTERRUPT)
config |= MIPS24K_PMC_INTERRUPT_ENABLE;
- PMCDBG(MDP,ALL,2,"mips24k-get_perfctl ri=%d -> config=0x%x", ri, config);
+ PMCDBG2(MDP,ALL,2,"mips24k-get_perfctl ri=%d -> config=0x%x", ri, config);
return (config);
}
diff --git a/sys/dev/hwpmc/hwpmc_mips74k.c b/sys/dev/hwpmc/hwpmc_mips74k.c
index 3a5ff33..59f677d 100644
--- a/sys/dev/hwpmc/hwpmc_mips74k.c
+++ b/sys/dev/hwpmc/hwpmc_mips74k.c
@@ -255,7 +255,7 @@ mips_get_perfctl(int cpu, int ri, uint32_t event, uint32_t caps)
if (caps & PMC_CAP_INTERRUPT)
config |= MIPS74K_PMC_INTERRUPT_ENABLE;
- PMCDBG(MDP,ALL,2,"mips74k-get_perfctl ri=%d -> config=0x%x", ri, config);
+ PMCDBG2(MDP,ALL,2,"mips74k-get_perfctl ri=%d -> config=0x%x", ri, config);
return (config);
}
diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c
index cb8ed37..3793aa2 100644
--- a/sys/dev/hwpmc/hwpmc_mod.c
+++ b/sys/dev/hwpmc/hwpmc_mod.c
@@ -173,7 +173,7 @@ static struct pmc_classdep **pmc_rowindex_to_classdep;
* Prototypes
*/
-#ifdef DEBUG
+#ifdef HWPMC_DEBUG
static int pmc_debugflags_sysctl_handler(SYSCTL_HANDLER_ARGS);
static int pmc_debugflags_parse(char *newstr, char *fence);
#endif
@@ -238,7 +238,7 @@ static int pmc_callchaindepth = PMC_CALLCHAIN_DEPTH;
SYSCTL_INT(_kern_hwpmc, OID_AUTO, callchaindepth, CTLFLAG_RDTUN,
&pmc_callchaindepth, 0, "depth of call chain records");
-#ifdef DEBUG
+#ifdef HWPMC_DEBUG
struct pmc_debugflags pmc_debugflags = PMC_DEBUG_DEFAULT_FLAGS;
char pmc_debugstr[PMC_DEBUG_STRSIZE];
TUNABLE_STR(PMC_SYSCTL_NAME_PREFIX "debugflags", pmc_debugstr,
@@ -337,7 +337,7 @@ static moduledata_t pmc_mod = {
DECLARE_MODULE(pmc, pmc_mod, SI_SUB_SMP, SI_ORDER_ANY);
MODULE_VERSION(pmc, PMC_VERSION);
-#ifdef DEBUG
+#ifdef HWPMC_DEBUG
enum pmc_dbgparse_state {
PMCDS_WS, /* in whitespace */
PMCDS_MAJOR, /* seen a major keyword */
@@ -651,12 +651,12 @@ pmc_ri_to_classdep(struct pmc_mdep *md, int ri, int *adjri)
static void
pmc_save_cpu_binding(struct pmc_binding *pb)
{
- PMCDBG(CPU,BND,2, "%s", "save-cpu");
+ PMCDBG0(CPU,BND,2, "save-cpu");
thread_lock(curthread);
pb->pb_bound = sched_is_bound(curthread);
pb->pb_cpu = curthread->td_oncpu;
thread_unlock(curthread);
- PMCDBG(CPU,BND,2, "save-cpu cpu=%d", pb->pb_cpu);
+ PMCDBG1(CPU,BND,2, "save-cpu cpu=%d", pb->pb_cpu);
}
/*
@@ -666,7 +666,7 @@ pmc_save_cpu_binding(struct pmc_binding *pb)
static void
pmc_restore_cpu_binding(struct pmc_binding *pb)
{
- PMCDBG(CPU,BND,2, "restore-cpu curcpu=%d restore=%d",
+ PMCDBG2(CPU,BND,2, "restore-cpu curcpu=%d restore=%d",
curthread->td_oncpu, pb->pb_cpu);
thread_lock(curthread);
if (pb->pb_bound)
@@ -674,7 +674,7 @@ pmc_restore_cpu_binding(struct pmc_binding *pb)
else
sched_unbind(curthread);
thread_unlock(curthread);
- PMCDBG(CPU,BND,2, "%s", "restore-cpu done");
+ PMCDBG0(CPU,BND,2, "restore-cpu done");
}
/*
@@ -691,7 +691,7 @@ pmc_select_cpu(int cpu)
KASSERT(pmc_cpu_is_active(cpu), ("[pmc,%d] selecting inactive "
"CPU %d", __LINE__, cpu));
- PMCDBG(CPU,SEL,2, "select-cpu cpu=%d", cpu);
+ PMCDBG1(CPU,SEL,2, "select-cpu cpu=%d", cpu);
thread_lock(curthread);
sched_bind(curthread, cpu);
thread_unlock(curthread);
@@ -700,7 +700,7 @@ pmc_select_cpu(int cpu)
("[pmc,%d] CPU not bound [cpu=%d, curr=%d]", __LINE__,
cpu, curthread->td_oncpu));
- PMCDBG(CPU,SEL,2, "select-cpu cpu=%d ok", cpu);
+ PMCDBG1(CPU,SEL,2, "select-cpu cpu=%d ok", cpu);
}
/*
@@ -742,14 +742,14 @@ pmc_remove_owner(struct pmc_owner *po)
sx_assert(&pmc_sx, SX_XLOCKED);
- PMCDBG(OWN,ORM,1, "remove-owner po=%p", po);
+ PMCDBG1(OWN,ORM,1, "remove-owner po=%p", po);
/* Remove descriptor from the owner hash table */
LIST_REMOVE(po, po_next);
/* release all owned PMC descriptors */
LIST_FOREACH_SAFE(pm, &po->po_pmcs, pm_next, tmp) {
- PMCDBG(OWN,ORM,2, "pmc=%p", pm);
+ PMCDBG1(OWN,ORM,2, "pmc=%p", pm);
KASSERT(pm->pm_owner == po,
("[pmc,%d] owner %p != po %p", __LINE__, pm->pm_owner, po));
@@ -775,7 +775,7 @@ static void
pmc_maybe_remove_owner(struct pmc_owner *po)
{
- PMCDBG(OWN,OMR,1, "maybe-remove-owner po=%p", po);
+ PMCDBG1(OWN,OMR,1, "maybe-remove-owner po=%p", po);
/*
* Remove owner record if
@@ -813,10 +813,10 @@ pmc_link_target_process(struct pmc *pm, struct pmc_process *pp)
ri = PMC_TO_ROWINDEX(pm);
- PMCDBG(PRC,TLK,1, "link-target pmc=%p ri=%d pmc-process=%p",
+ PMCDBG3(PRC,TLK,1, "link-target pmc=%p ri=%d pmc-process=%p",
pm, ri, pp);
-#ifdef DEBUG
+#ifdef HWPMC_DEBUG
LIST_FOREACH(pt, &pm->pm_targets, pt_next)
if (pt->pt_process == pp)
KASSERT(0, ("[pmc,%d] pp %p already in pmc %p targets",
@@ -866,7 +866,7 @@ pmc_unlink_target_process(struct pmc *pm, struct pmc_process *pp)
ri = PMC_TO_ROWINDEX(pm);
- PMCDBG(PRC,TUL,1, "unlink-target pmc=%p ri=%d pmc-process=%p",
+ PMCDBG3(PRC,TUL,1, "unlink-target pmc=%p ri=%d pmc-process=%p",
pm, ri, pp);
KASSERT(pp->pp_pmcs[ri].pp_pmc == pm,
@@ -902,7 +902,7 @@ pmc_unlink_target_process(struct pmc *pm, struct pmc_process *pp)
kern_psignal(p, SIGIO);
PROC_UNLOCK(p);
- PMCDBG(PRC,SIG,2, "signalling proc=%p signal=%d", p,
+ PMCDBG2(PRC,SIG,2, "signalling proc=%p signal=%d", p,
SIGIO);
}
}
@@ -975,7 +975,7 @@ pmc_attach_one_process(struct proc *p, struct pmc *pm)
sx_assert(&pmc_sx, SX_XLOCKED);
- PMCDBG(PRC,ATT,2, "attach-one pm=%p ri=%d proc=%p (%d, %s)", pm,
+ PMCDBG5(PRC,ATT,2, "attach-one pm=%p ri=%d proc=%p (%d, %s)", pm,
PMC_TO_ROWINDEX(pm), p, p->p_pid, p->p_comm);
/*
@@ -1040,7 +1040,7 @@ pmc_attach_process(struct proc *p, struct pmc *pm)
sx_assert(&pmc_sx, SX_XLOCKED);
- PMCDBG(PRC,ATT,1, "attach pm=%p ri=%d proc=%p (%d, %s)", pm,
+ PMCDBG5(PRC,ATT,1, "attach pm=%p ri=%d proc=%p (%d, %s)", pm,
PMC_TO_ROWINDEX(pm), p, p->p_pid, p->p_comm);
@@ -1107,7 +1107,7 @@ pmc_detach_one_process(struct proc *p, struct pmc *pm, int flags)
ri = PMC_TO_ROWINDEX(pm);
- PMCDBG(PRC,ATT,2, "detach-one pm=%p ri=%d proc=%p (%d, %s) flags=0x%x",
+ PMCDBG6(PRC,ATT,2, "detach-one pm=%p ri=%d proc=%p (%d, %s) flags=0x%x",
pm, ri, p, p->p_pid, p->p_comm, flags);
if ((pp = pmc_find_process_descriptor(p, 0)) == NULL)
@@ -1157,7 +1157,7 @@ pmc_detach_process(struct proc *p, struct pmc *pm)
sx_assert(&pmc_sx, SX_XLOCKED);
- PMCDBG(PRC,ATT,1, "detach pm=%p ri=%d proc=%p (%d, %s)", pm,
+ PMCDBG5(PRC,ATT,1, "detach pm=%p ri=%d proc=%p (%d, %s)", pm,
PMC_TO_ROWINDEX(pm), p, p->p_pid, p->p_comm);
if ((pm->pm_flags & PMC_F_DESCENDANTS) == 0)
@@ -1228,7 +1228,7 @@ pmc_process_csw_in(struct thread *td)
cpu = PCPU_GET(cpuid); /* td->td_oncpu is invalid */
- PMCDBG(CSW,SWI,1, "cpu=%d proc=%p (%d, %s) pp=%p", cpu, p,
+ PMCDBG5(CSW,SWI,1, "cpu=%d proc=%p (%d, %s) pp=%p", cpu, p,
p->p_pid, p->p_comm, pp);
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
@@ -1295,7 +1295,7 @@ pmc_process_csw_in(struct thread *td)
mtx_pool_unlock_spin(pmc_mtxpool, pm);
}
- PMCDBG(CSW,SWI,1,"cpu=%d ri=%d new=%jd", cpu, ri, newvalue);
+ PMCDBG3(CSW,SWI,1,"cpu=%d ri=%d new=%jd", cpu, ri, newvalue);
pcd->pcd_write_pmc(cpu, adjri, newvalue);
pcd->pcd_start_pmc(cpu, adjri);
@@ -1356,7 +1356,7 @@ pmc_process_csw_out(struct thread *td)
cpu = PCPU_GET(cpuid); /* td->td_oncpu is invalid */
- PMCDBG(CSW,SWO,1, "cpu=%d proc=%p (%d, %s) pp=%p", cpu, p,
+ PMCDBG5(CSW,SWO,1, "cpu=%d proc=%p (%d, %s) pp=%p", cpu, p,
p->p_pid, p->p_comm, pp);
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
@@ -1418,7 +1418,7 @@ pmc_process_csw_out(struct thread *td)
tmp = newvalue - PMC_PCPU_SAVED(cpu,ri);
- PMCDBG(CSW,SWO,1,"cpu=%d ri=%d tmp=%jd", cpu, ri,
+ PMCDBG3(CSW,SWO,1,"cpu=%d ri=%d tmp=%jd", cpu, ri,
tmp);
if (mode == PMC_MODE_TS) {
@@ -1575,7 +1575,7 @@ pmc_log_kernel_mappings(struct pmc *pm)
*/
kmbase = linker_hwpmc_list_objects();
for (km = kmbase; km->pm_file != NULL; km++) {
- PMCDBG(LOG,REG,1,"%s %p", (char *) km->pm_file,
+ PMCDBG2(LOG,REG,1,"%s %p", (char *) km->pm_file,
(void *) km->pm_address);
pmclog_process_map_in(po, (pid_t) -1, km->pm_address,
km->pm_file);
@@ -1616,7 +1616,7 @@ pmc_log_process_mappings(struct pmc_owner *po, struct proc *p)
for (entry = map->header.next; entry != &map->header; entry = entry->next) {
if (entry == NULL) {
- PMCDBG(LOG,OPS,2, "hwpmc: vm_map entry unexpectedly "
+ PMCDBG2(LOG,OPS,2, "hwpmc: vm_map entry unexpectedly "
"NULL! pid=%d vm_map=%p\n", p->p_pid, map);
break;
}
@@ -1649,7 +1649,7 @@ pmc_log_process_mappings(struct pmc_owner *po, struct proc *p)
* At this point lobj is the base vm_object and it is locked.
*/
if (lobj == NULL) {
- PMCDBG(LOG,OPS,2, "hwpmc: lobj unexpectedly NULL! pid=%d "
+ PMCDBG3(LOG,OPS,2, "hwpmc: lobj unexpectedly NULL! pid=%d "
"vm_map=%p vm_obj=%p\n", p->p_pid, map, obj);
VM_OBJECT_RUNLOCK(obj);
continue;
@@ -1784,7 +1784,7 @@ pmc_log_all_process_mappings(struct pmc_owner *po)
*/
-#ifdef DEBUG
+#ifdef HWPMC_DEBUG
const char *pmc_hooknames[] = {
/* these strings correspond to PMC_FN_* in <sys/pmckern.h> */
"",
@@ -1806,7 +1806,7 @@ static int
pmc_hook_handler(struct thread *td, int function, void *arg)
{
- PMCDBG(MOD,PMH,1, "hook td=%p func=%d \"%s\" arg=%p", td, function,
+ PMCDBG4(MOD,PMH,1, "hook td=%p func=%d \"%s\" arg=%p", td, function,
pmc_hooknames[function], arg);
switch (function)
@@ -1889,7 +1889,7 @@ pmc_hook_handler(struct thread *td, int function, void *arg)
free(freepath, M_TEMP);
- PMCDBG(PRC,EXC,1, "exec proc=%p (%d, %s) cred-changed=%d",
+ PMCDBG4(PRC,EXC,1, "exec proc=%p (%d, %s) cred-changed=%d",
p, p->p_pid, p->p_comm, pk->pm_credentialschanged);
if (pk->pm_credentialschanged == 0) /* no change */
@@ -2002,7 +2002,7 @@ pmc_hook_handler(struct thread *td, int function, void *arg)
break;
default:
-#ifdef DEBUG
+#ifdef HWPMC_DEBUG
KASSERT(0, ("[pmc,%d] unknown hook %d\n", __LINE__, function));
#endif
break;
@@ -2034,7 +2034,7 @@ pmc_allocate_owner_descriptor(struct proc *p)
TAILQ_INIT(&po->po_logbuffers);
mtx_init(&po->po_mtx, "pmc-owner-mtx", "pmc-per-proc", MTX_SPIN);
- PMCDBG(OWN,ALL,1, "allocate-owner proc=%p (%d, %s) pmc-owner=%p",
+ PMCDBG4(OWN,ALL,1, "allocate-owner proc=%p (%d, %s) pmc-owner=%p",
p, p->p_pid, p->p_comm, po);
return po;
@@ -2044,7 +2044,7 @@ static void
pmc_destroy_owner_descriptor(struct pmc_owner *po)
{
- PMCDBG(OWN,REL,1, "destroy-owner po=%p proc=%p (%d, %s)",
+ PMCDBG4(OWN,REL,1, "destroy-owner po=%p proc=%p (%d, %s)",
po, po->po_owner, po->po_owner->p_pid, po->po_owner->p_comm);
mtx_destroy(&po->po_mtx);
@@ -2135,7 +2135,7 @@ pmc_find_owner_descriptor(struct proc *p)
if (po->po_owner == p)
break;
- PMCDBG(OWN,FND,1, "find-owner proc=%p (%d, %s) hindex=0x%x -> "
+ PMCDBG5(OWN,FND,1, "find-owner proc=%p (%d, %s) hindex=0x%x -> "
"pmc-owner=%p", p, p->p_pid, p->p_comm, hindex, po);
return po;
@@ -2155,7 +2155,7 @@ pmc_allocate_pmc_descriptor(void)
pmc = malloc(sizeof(struct pmc), M_PMC, M_WAITOK|M_ZERO);
- PMCDBG(PMC,ALL,1, "allocate-pmc -> pmc=%p", pmc);
+ PMCDBG1(PMC,ALL,1, "allocate-pmc -> pmc=%p", pmc);
return pmc;
}
@@ -2185,7 +2185,7 @@ pmc_destroy_pmc_descriptor(struct pmc *pm)
static void
pmc_wait_for_pmc_idle(struct pmc *pm)
{
-#ifdef DEBUG
+#ifdef HWPMC_DEBUG
volatile int maxloop;
maxloop = 100 * pmc_cpu_max();
@@ -2195,7 +2195,7 @@ pmc_wait_for_pmc_idle(struct pmc *pm)
* comes down to zero.
*/
while (atomic_load_acq_32(&pm->pm_runcount) > 0) {
-#ifdef DEBUG
+#ifdef HWPMC_DEBUG
maxloop--;
KASSERT(maxloop > 0,
("[pmc,%d] (ri%d, rc%d) waiting too long for "
@@ -2238,7 +2238,7 @@ pmc_release_pmc_descriptor(struct pmc *pm)
pcd = pmc_ri_to_classdep(md, ri, &adjri);
mode = PMC_TO_MODE(pm);
- PMCDBG(PMC,REL,1, "release-pmc pmc=%p ri=%d mode=%d", pm, ri,
+ PMCDBG3(PMC,REL,1, "release-pmc pmc=%p ri=%d mode=%d", pm, ri,
mode);
/*
@@ -2266,14 +2266,14 @@ pmc_release_pmc_descriptor(struct pmc *pm)
KASSERT(phw->phw_pmc == pm,
("[pmc, %d] pmc ptr ri(%d) hw(%p) pm(%p)",
__LINE__, ri, phw->phw_pmc, pm));
- PMCDBG(PMC,REL,2, "stopping cpu=%d ri=%d", cpu, ri);
+ PMCDBG2(PMC,REL,2, "stopping cpu=%d ri=%d", cpu, ri);
critical_enter();
pcd->pcd_stop_pmc(cpu, adjri);
critical_exit();
}
- PMCDBG(PMC,REL,2, "decfg cpu=%d ri=%d", cpu, ri);
+ PMCDBG2(PMC,REL,2, "decfg cpu=%d ri=%d", cpu, ri);
critical_enter();
pcd->pcd_config_pmc(cpu, adjri, NULL);
@@ -2329,7 +2329,7 @@ pmc_release_pmc_descriptor(struct pmc *pm)
pp = ptgt->pt_process;
pmc_unlink_target_process(pm, pp); /* frees 'ptgt' */
- PMCDBG(PMC,REL,3, "pp->refcnt=%d", pp->pp_refcnt);
+ PMCDBG1(PMC,REL,3, "pp->refcnt=%d", pp->pp_refcnt);
/*
* If the target process record shows that no
@@ -2395,7 +2395,7 @@ pmc_register_owner(struct proc *p, struct pmc *pmc)
if (po->po_flags & PMC_PO_OWNS_LOGFILE)
pmclog_process_pmcallocate(pmc);
- PMCDBG(PMC,REG,1, "register-owner pmc-owner=%p pmc=%p",
+ PMCDBG2(PMC,REG,1, "register-owner pmc-owner=%p pmc=%p",
po, pmc);
return 0;
@@ -2433,7 +2433,7 @@ pmc_can_allocate_rowindex(struct proc *p, unsigned int ri, int cpu)
struct pmc_owner *po;
struct pmc_process *pp;
- PMCDBG(PMC,ALR,1, "can-allocate-rowindex proc=%p (%d, %s) ri=%d "
+ PMCDBG5(PMC,ALR,1, "can-allocate-rowindex proc=%p (%d, %s) ri=%d "
"cpu=%d", p, p->p_pid, p->p_comm, ri, cpu);
/*
@@ -2463,7 +2463,7 @@ pmc_can_allocate_rowindex(struct proc *p, unsigned int ri, int cpu)
if (pp->pp_pmcs[ri].pp_pmc)
return EEXIST;
- PMCDBG(PMC,ALR,2, "can-allocate-rowindex proc=%p (%d, %s) ri=%d ok",
+ PMCDBG4(PMC,ALR,2, "can-allocate-rowindex proc=%p (%d, %s) ri=%d ok",
p, p->p_pid, p->p_comm, ri);
return 0;
@@ -2481,7 +2481,7 @@ pmc_can_allocate_row(int ri, enum pmc_mode mode)
sx_assert(&pmc_sx, SX_XLOCKED);
- PMCDBG(PMC,ALR,1, "can-allocate-row ri=%d mode=%d", ri, mode);
+ PMCDBG2(PMC,ALR,1, "can-allocate-row ri=%d mode=%d", ri, mode);
if (PMC_IS_SYSTEM_MODE(mode))
disp = PMC_DISP_STANDALONE;
@@ -2508,7 +2508,7 @@ pmc_can_allocate_row(int ri, enum pmc_mode mode)
* All OK
*/
- PMCDBG(PMC,ALR,2, "can-allocate-row ri=%d mode=%d ok", ri, mode);
+ PMCDBG2(PMC,ALR,2, "can-allocate-row ri=%d mode=%d ok", ri, mode);
return 0;
@@ -2541,7 +2541,7 @@ pmc_find_pmc(pmc_id_t pmcid, struct pmc **pmc)
struct pmc *pm;
struct pmc_owner *po;
- PMCDBG(PMC,FND,1, "find-pmc id=%d", pmcid);
+ PMCDBG1(PMC,FND,1, "find-pmc id=%d", pmcid);
if ((po = pmc_find_owner_descriptor(curthread->td_proc)) == NULL)
return ESRCH;
@@ -2549,7 +2549,7 @@ pmc_find_pmc(pmc_id_t pmcid, struct pmc **pmc)
if ((pm = pmc_find_pmc_descriptor_in_process(po, pmcid)) == NULL)
return EINVAL;
- PMCDBG(PMC,FND,2, "find-pmc id=%d -> pmc=%p", pmcid, pm);
+ PMCDBG2(PMC,FND,2, "find-pmc id=%d -> pmc=%p", pmcid, pm);
*pmc = pm;
return 0;
@@ -2577,7 +2577,7 @@ pmc_start(struct pmc *pm)
error = 0;
- PMCDBG(PMC,OPS,1, "start pmc=%p mode=%d ri=%d", pm, mode, ri);
+ PMCDBG3(PMC,OPS,1, "start pmc=%p mode=%d ri=%d", pm, mode, ri);
po = pm->pm_owner;
@@ -2633,7 +2633,7 @@ pmc_start(struct pmc *pm)
if (po->po_sscount == 0) {
LIST_INSERT_HEAD(&pmc_ss_owners, po, po_ssnext);
atomic_add_rel_int(&pmc_ss_count, 1);
- PMCDBG(PMC,OPS,1, "po=%p in global list", po);
+ PMCDBG1(PMC,OPS,1, "po=%p in global list", po);
}
po->po_sscount++;
@@ -2696,7 +2696,7 @@ pmc_stop(struct pmc *pm)
KASSERT(pm != NULL, ("[pmc,%d] null pmc", __LINE__));
- PMCDBG(PMC,OPS,1, "stop pmc=%p mode=%d ri=%d", pm,
+ PMCDBG3(PMC,OPS,1, "stop pmc=%p mode=%d ri=%d", pm,
PMC_TO_MODE(pm), PMC_TO_ROWINDEX(pm));
pm->pm_state = PMC_STATE_STOPPED;
@@ -2751,7 +2751,7 @@ pmc_stop(struct pmc *pm)
if (po->po_sscount == 0) {
atomic_subtract_rel_int(&pmc_ss_count, 1);
LIST_REMOVE(po, po_ssnext);
- PMCDBG(PMC,OPS,2,"po=%p removed from global list", po);
+ PMCDBG1(PMC,OPS,2,"po=%p removed from global list", po);
}
}
@@ -2759,7 +2759,7 @@ pmc_stop(struct pmc *pm)
}
-#ifdef DEBUG
+#ifdef HWPMC_DEBUG
static const char *pmc_op_to_name[] = {
#undef __PMC_OP
#define __PMC_OP(N, D) #N ,
@@ -2804,7 +2804,7 @@ pmc_syscall_handler(struct thread *td, void *syscall_args)
op = c->pmop_code;
arg = c->pmop_data;
- PMCDBG(MOD,PMS,1, "syscall op=%d \"%s\" arg=%p", op,
+ PMCDBG3(MOD,PMS,1, "syscall op=%d \"%s\" arg=%p", op,
pmc_op_to_name[op], arg);
error = 0;
@@ -3317,7 +3317,7 @@ pmc_syscall_handler(struct thread *td, void *syscall_args)
break;
}
- PMCDBG(PMC,ALL,2, "event=%d caps=0x%x mode=%d cpu=%d",
+ PMCDBG4(PMC,ALL,2, "event=%d caps=0x%x mode=%d cpu=%d",
pa.pm_ev, caps, mode, cpu);
pmc = pmc_allocate_pmc_descriptor();
@@ -3379,7 +3379,7 @@ pmc_syscall_handler(struct thread *td, void *syscall_args)
/* Fill in the correct value in the ID field */
pmc->pm_id = PMC_ID_MAKE_ID(cpu,mode,pa.pm_class,n);
- PMCDBG(PMC,ALL,2, "ev=%d class=%d mode=%d n=%d -> pmcid=%x",
+ PMCDBG5(PMC,ALL,2, "ev=%d class=%d mode=%d n=%d -> pmcid=%x",
pmc->pm_event, pa.pm_class, mode, n, pmc->pm_id);
/* Process mode PMCs with logging enabled need log files */
@@ -3702,7 +3702,7 @@ pmc_syscall_handler(struct thread *td, void *syscall_args)
break;
ri = 0;
- PMCDBG(PMC,OPS,1, "rw id=%d flags=0x%x", prw.pm_pmcid,
+ PMCDBG2(PMC,OPS,1, "rw id=%d flags=0x%x", prw.pm_pmcid,
prw.pm_flags);
/* must have at least one flag set */
@@ -3798,12 +3798,12 @@ pmc_syscall_handler(struct thread *td, void *syscall_args)
pprw = (struct pmc_op_pmcrw *) arg;
-#ifdef DEBUG
+#ifdef HWPMC_DEBUG
if (prw.pm_flags & PMC_F_NEWVALUE)
- PMCDBG(PMC,OPS,2, "rw id=%d new %jx -> old %jx",
+ PMCDBG3(PMC,OPS,2, "rw id=%d new %jx -> old %jx",
ri, prw.pm_value, oldvalue);
else if (prw.pm_flags & PMC_F_OLDVALUE)
- PMCDBG(PMC,OPS,2, "rw id=%d -> old %jx", ri, oldvalue);
+ PMCDBG2(PMC,OPS,2, "rw id=%d -> old %jx", ri, oldvalue);
#endif
/* return old value if requested */
@@ -4046,7 +4046,7 @@ pmc_process_interrupt(int cpu, int ring, struct pmc *pm, struct trapframe *tf,
if (ps->ps_nsamples) { /* in use, reader hasn't caught up */
pm->pm_stalled = 1;
atomic_add_int(&pmc_stats.pm_intr_bufferfull, 1);
- PMCDBG(SAM,INT,1,"(spc) cpu=%d pm=%p tf=%p um=%d wr=%d rd=%d",
+ PMCDBG6(SAM,INT,1,"(spc) cpu=%d pm=%p tf=%p um=%d wr=%d rd=%d",
cpu, pm, (void *) tf, inuserspace,
(int) (psb->ps_write - psb->ps_samples),
(int) (psb->ps_read - psb->ps_samples));
@@ -4056,7 +4056,7 @@ pmc_process_interrupt(int cpu, int ring, struct pmc *pm, struct trapframe *tf,
/* Fill in entry. */
- PMCDBG(SAM,INT,1,"cpu=%d pm=%p tf=%p um=%d wr=%d rd=%d", cpu, pm,
+ PMCDBG6(SAM,INT,1,"cpu=%d pm=%p tf=%p um=%d wr=%d rd=%d", cpu, pm,
(void *) tf, inuserspace,
(int) (psb->ps_write - psb->ps_samples),
(int) (psb->ps_read - psb->ps_samples));
@@ -4239,7 +4239,7 @@ pmc_process_samples(int cpu, int ring)
break;
}
- PMCDBG(SAM,OPS,1,"cpu=%d pm=%p n=%d fl=%x wr=%d rd=%d", cpu,
+ PMCDBG6(SAM,OPS,1,"cpu=%d pm=%p n=%d fl=%x wr=%d rd=%d", cpu,
pm, ps->ps_nsamples, ps->ps_flags,
(int) (psb->ps_write - psb->ps_samples),
(int) (psb->ps_read - psb->ps_samples));
@@ -4355,7 +4355,7 @@ pmc_process_exit(void *arg __unused, struct proc *p)
return;
PMC_GET_SX_XLOCK();
- PMCDBG(PRC,EXT,1,"process-exit proc=%p (%d, %s)", p, p->p_pid,
+ PMCDBG3(PRC,EXT,1,"process-exit proc=%p (%d, %s)", p, p->p_pid,
p->p_comm);
/*
@@ -4370,7 +4370,7 @@ pmc_process_exit(void *arg __unused, struct proc *p)
* entry from our target process hash table, using
* PMC_FLAG_REMOVE.
*/
- PMCDBG(PRC,EXT,1, "process-exit proc=%p (%d, %s)", p, p->p_pid,
+ PMCDBG3(PRC,EXT,1, "process-exit proc=%p (%d, %s)", p, p->p_pid,
p->p_comm);
critical_enter(); /* no preemption */
@@ -4380,7 +4380,7 @@ pmc_process_exit(void *arg __unused, struct proc *p)
if ((pp = pmc_find_process_descriptor(p,
PMC_FLAG_REMOVE)) != NULL) {
- PMCDBG(PRC,EXT,2,
+ PMCDBG2(PRC,EXT,2,
"process-exit proc=%p pmc-process=%p", p, pp);
/*
@@ -4403,13 +4403,13 @@ pmc_process_exit(void *arg __unused, struct proc *p)
(void) (*pcd->pcd_get_config)(cpu, adjri, &pm);
- PMCDBG(PRC,EXT,2, "ri=%d pm=%p", ri, pm);
+ PMCDBG2(PRC,EXT,2, "ri=%d pm=%p", ri, pm);
if (pm == NULL ||
!PMC_IS_VIRTUAL_MODE(PMC_TO_MODE(pm)))
continue;
- PMCDBG(PRC,EXT,2, "ppmcs[%d]=%p pm=%p "
+ PMCDBG4(PRC,EXT,2, "ppmcs[%d]=%p pm=%p "
"state=%d", ri, pp->pp_pmcs[ri].pp_pmc,
pm, pm->pm_state);
@@ -4525,7 +4525,7 @@ pmc_process_fork(void *arg __unused, struct proc *p1, struct proc *newproc,
return;
PMC_GET_SX_XLOCK();
- PMCDBG(PMC,FRK,1, "process-fork proc=%p (%d, %s) -> %p", p1,
+ PMCDBG4(PMC,FRK,1, "process-fork proc=%p (%d, %s) -> %p", p1,
p1->p_pid, p1->p_comm, newproc);
/*
@@ -4712,7 +4712,7 @@ pmc_initialize(void)
md = NULL;
error = 0;
-#ifdef DEBUG
+#ifdef HWPMC_DEBUG
/* parse debug flags first */
if (TUNABLE_STR_FETCH(PMC_SYSCTL_NAME_PREFIX "debugflags",
pmc_debugstr, sizeof(pmc_debugstr)))
@@ -4720,7 +4720,7 @@ pmc_initialize(void)
pmc_debugstr+strlen(pmc_debugstr));
#endif
- PMCDBG(MOD,INI,0, "PMC Initialize (version %x)", PMC_VERSION);
+ PMCDBG1(MOD,INI,0, "PMC Initialize (version %x)", PMC_VERSION);
/* check kernel version */
if (pmc_kernel_version != PMC_VERSION) {
@@ -4881,7 +4881,7 @@ pmc_initialize(void)
pmc_mtxpool = mtx_pool_create("pmc-leaf", pmc_mtxpool_size,
MTX_SPIN);
- PMCDBG(MOD,INI,1, "pmc_ownerhash=%p, mask=0x%lx "
+ PMCDBG4(MOD,INI,1, "pmc_ownerhash=%p, mask=0x%lx "
"targethash=%p mask=0x%lx", pmc_ownerhash, pmc_ownerhashmask,
pmc_processhash, pmc_processhashmask);
@@ -4933,11 +4933,11 @@ pmc_cleanup(void)
struct pmc_ownerhash *ph;
struct pmc_owner *po, *tmp;
struct pmc_binding pb;
-#ifdef DEBUG
+#ifdef HWPMC_DEBUG
struct pmc_processhash *prh;
#endif
- PMCDBG(MOD,INI,0, "%s", "cleanup");
+ PMCDBG0(MOD,INI,0, "cleanup");
/* switch off sampling */
CPU_ZERO(&pmc_cpumask);
@@ -4966,7 +4966,7 @@ pmc_cleanup(void)
pmc_remove_owner(po);
/* send SIGBUS to owner processes */
- PMCDBG(MOD,INI,2, "cleanup signal proc=%p "
+ PMCDBG3(MOD,INI,2, "cleanup signal proc=%p "
"(%d, %s)", po->po_owner,
po->po_owner->p_pid,
po->po_owner->p_comm);
@@ -4985,15 +4985,15 @@ pmc_cleanup(void)
mtx_destroy(&pmc_processhash_mtx);
if (pmc_processhash) {
-#ifdef DEBUG
+#ifdef HWPMC_DEBUG
struct pmc_process *pp;
- PMCDBG(MOD,INI,3, "%s", "destroy process hash");
+ PMCDBG0(MOD,INI,3, "destroy process hash");
for (prh = pmc_processhash;
prh <= &pmc_processhash[pmc_processhashmask];
prh++)
LIST_FOREACH(pp, prh, pp_next)
- PMCDBG(MOD,INI,3, "pid=%d", pp->pp_proc->p_pid);
+ PMCDBG1(MOD,INI,3, "pid=%d", pp->pp_proc->p_pid);
#endif
hashdestroy(pmc_processhash, M_PMC, pmc_processhashmask);
@@ -5001,7 +5001,7 @@ pmc_cleanup(void)
}
if (pmc_ownerhash) {
- PMCDBG(MOD,INI,3, "%s", "destroy owner hash");
+ PMCDBG0(MOD,INI,3, "destroy owner hash");
hashdestroy(pmc_ownerhash, M_PMC, pmc_ownerhashmask);
pmc_ownerhash = NULL;
}
@@ -5014,11 +5014,11 @@ pmc_cleanup(void)
/* do processor and pmc-class dependent cleanup */
maxcpu = pmc_cpu_max();
- PMCDBG(MOD,INI,3, "%s", "md cleanup");
+ PMCDBG0(MOD,INI,3, "md cleanup");
if (md) {
pmc_save_cpu_binding(&pb);
for (cpu = 0; cpu < maxcpu; cpu++) {
- PMCDBG(MOD,INI,1,"pmc-cleanup cpu=%d pcs=%p",
+ PMCDBG2(MOD,INI,1,"pmc-cleanup cpu=%d pcs=%p",
cpu, pmc_pcpu[cpu]);
if (!pmc_cpu_is_active(cpu) || pmc_pcpu[cpu] == NULL)
continue;
@@ -5094,7 +5094,7 @@ load (struct module *module __unused, int cmd, void *arg __unused)
error = pmc_initialize();
if (error != 0)
break;
- PMCDBG(MOD,INI,1, "syscall=%d maxcpu=%d",
+ PMCDBG2(MOD,INI,1, "syscall=%d maxcpu=%d",
pmc_syscall_num, pmc_cpu_max());
break;
@@ -5102,7 +5102,7 @@ load (struct module *module __unused, int cmd, void *arg __unused)
case MOD_UNLOAD :
case MOD_SHUTDOWN:
pmc_cleanup();
- PMCDBG(MOD,INI,1, "%s", "unloaded");
+ PMCDBG0(MOD,INI,1, "unloaded");
break;
default :
diff --git a/sys/dev/hwpmc/hwpmc_mpc7xxx.c b/sys/dev/hwpmc/hwpmc_mpc7xxx.c
index eaa440e..296bd37 100644
--- a/sys/dev/hwpmc/hwpmc_mpc7xxx.c
+++ b/sys/dev/hwpmc/hwpmc_mpc7xxx.c
@@ -384,7 +384,7 @@ mpc7xxx_read_pmc(int cpu, int ri, pmc_value_t *v)
ri));
tmp = mpc7xxx_pmcn_read(ri);
- PMCDBG(MDP,REA,2,"ppc-read id=%d -> %jd", ri, tmp);
+ PMCDBG2(MDP,REA,2,"ppc-read id=%d -> %jd", ri, tmp);
if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
*v = POWERPC_PERFCTR_VALUE_TO_RELOAD_COUNT(tmp);
else
@@ -408,7 +408,7 @@ mpc7xxx_write_pmc(int cpu, int ri, pmc_value_t v)
if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
v = POWERPC_RELOAD_COUNT_TO_PERFCTR_VALUE(v);
- PMCDBG(MDP,WRI,1,"powerpc-write cpu=%d ri=%d v=%jx", cpu, ri, v);
+ PMCDBG3(MDP,WRI,1,"powerpc-write cpu=%d ri=%d v=%jx", cpu, ri, v);
mpc7xxx_pmcn_write(ri, v);
@@ -420,7 +420,7 @@ mpc7xxx_config_pmc(int cpu, int ri, struct pmc *pm)
{
struct pmc_hw *phw;
- PMCDBG(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm);
+ PMCDBG3(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm);
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[powerpc,%d] illegal CPU value %d", __LINE__, cpu));
@@ -559,7 +559,7 @@ mpc7xxx_pcpu_init(struct pmc_mdep *md, int cpu)
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[powerpc,%d] wrong cpu number %d", __LINE__, cpu));
- PMCDBG(MDP,INI,1,"powerpc-init cpu=%d", cpu);
+ PMCDBG1(MDP,INI,1,"powerpc-init cpu=%d", cpu);
powerpc_pcpu[cpu] = pac = malloc(sizeof(struct powerpc_cpu), M_PMC,
M_WAITOK|M_ZERO);
@@ -638,7 +638,7 @@ mpc7xxx_allocate_pmc(int cpu, int ri, struct pmc *pm,
pm->pm_md.pm_powerpc.pm_powerpc_evsel = config;
- PMCDBG(MDP,ALL,2,"powerpc-allocate ri=%d -> config=0x%x", ri, config);
+ PMCDBG2(MDP,ALL,2,"powerpc-allocate ri=%d -> config=0x%x", ri, config);
return 0;
}
@@ -671,7 +671,7 @@ mpc7xxx_intr(int cpu, struct trapframe *tf)
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[powerpc,%d] out of range CPU %d", __LINE__, cpu));
- PMCDBG(MDP,INT,1, "cpu=%d tf=%p um=%d", cpu, (void *) tf,
+ PMCDBG3(MDP,INT,1, "cpu=%d tf=%p um=%d", cpu, (void *) tf,
TRAPF_USERMODE(tf));
retval = 0;
diff --git a/sys/dev/hwpmc/hwpmc_octeon.c b/sys/dev/hwpmc/hwpmc_octeon.c
index 824a7b0..b614573 100644
--- a/sys/dev/hwpmc/hwpmc_octeon.c
+++ b/sys/dev/hwpmc/hwpmc_octeon.c
@@ -189,7 +189,8 @@ mips_get_perfctl(int cpu, int ri, uint32_t event, uint32_t caps)
if (caps & PMC_CAP_INTERRUPT)
control.s.ie = 1;
- PMCDBG(MDP,ALL,2,"mips-allocate ri=%d -> config=0x%x", ri, control.u32);
+ PMCDBG2(MDP,ALL,2,"mips-allocate ri=%d -> config=0x%x", ri,
+ control.u32);
return (control.u32);
}
diff --git a/sys/dev/hwpmc/hwpmc_piv.c b/sys/dev/hwpmc/hwpmc_piv.c
index ff47cb8..872ad89 100644
--- a/sys/dev/hwpmc/hwpmc_piv.c
+++ b/sys/dev/hwpmc/hwpmc_piv.c
@@ -563,7 +563,7 @@ p4_pcpu_init(struct pmc_mdep *md, int cpu)
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[p4,%d] insane cpu number %d", __LINE__, cpu));
- PMCDBG(MDP,INI,0, "p4-init cpu=%d is-primary=%d", cpu,
+ PMCDBG2(MDP,INI,0, "p4-init cpu=%d is-primary=%d", cpu,
pmc_cpu_is_primary(cpu) != 0);
first_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_P4].pcd_ri;
@@ -590,7 +590,7 @@ p4_pcpu_init(struct pmc_mdep *md, int cpu)
KASSERT(plc != pc, ("[p4,%d] per-cpu config error", __LINE__));
- PMCDBG(MDP,INI,1, "p4-init cpu=%d phycpu=%d pc=%p", cpu,
+ PMCDBG3(MDP,INI,1, "p4-init cpu=%d phycpu=%d pc=%p", cpu,
phycpu, pc);
KASSERT(pc, ("[p4,%d] Null Per-Cpu state cpu=%d phycpu=%d",
__LINE__, cpu, phycpu));
@@ -642,7 +642,7 @@ p4_pcpu_fini(struct pmc_mdep *md, int cpu)
struct p4_cpu *p4c;
struct pmc_cpu *pc;
- PMCDBG(MDP,INI,0, "p4-cleanup cpu=%d", cpu);
+ PMCDBG1(MDP,INI,0, "p4-cleanup cpu=%d", cpu);
pc = pmc_pcpu[cpu];
first_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_P4].pcd_ri;
@@ -702,7 +702,7 @@ p4_read_pmc(int cpu, int ri, pmc_value_t *v)
mode = PMC_TO_MODE(pm);
- PMCDBG(MDP,REA,1, "p4-read cpu=%d ri=%d mode=%d", cpu, ri, mode);
+ PMCDBG3(MDP,REA,1, "p4-read cpu=%d ri=%d mode=%d", cpu, ri, mode);
KASSERT(pd->pm_descr.pd_class == PMC_CLASS_P4,
("[p4,%d] unknown PMC class %d", __LINE__, pd->pm_descr.pd_class));
@@ -723,7 +723,7 @@ p4_read_pmc(int cpu, int ri, pmc_value_t *v)
else
*v = tmp;
- PMCDBG(MDP,REA,2, "p4-read -> %jx", *v);
+ PMCDBG1(MDP,REA,2, "p4-read -> %jx", *v);
return (0);
}
@@ -757,7 +757,7 @@ p4_write_pmc(int cpu, int ri, pmc_value_t v)
mode = PMC_TO_MODE(pm);
- PMCDBG(MDP,WRI,1, "p4-write cpu=%d ri=%d mode=%d v=%jx", cpu, ri,
+ PMCDBG4(MDP,WRI,1, "p4-write cpu=%d ri=%d mode=%d v=%jx", cpu, ri,
mode, v);
/*
@@ -800,7 +800,7 @@ p4_config_pmc(int cpu, int ri, struct pmc *pm)
KASSERT(ri >= 0 && ri < P4_NPMCS,
("[p4,%d] illegal row-index %d", __LINE__, ri));
- PMCDBG(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm);
+ PMCDBG3(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm);
pc = p4_pcpu[P4_TO_HTT_PRIMARY(cpu)];
phw = &pc->pc_p4pmcs[ri];
@@ -930,7 +930,7 @@ p4_allocate_pmc(int cpu, int ri, struct pmc *pm,
pd = &p4_pmcdesc[ri];
- PMCDBG(MDP,ALL,1, "p4-allocate ri=%d class=%d pmccaps=0x%x "
+ PMCDBG4(MDP,ALL,1, "p4-allocate ri=%d class=%d pmccaps=0x%x "
"reqcaps=0x%x", ri, pd->pm_descr.pd_class, pd->pm_descr.pd_caps,
pm->pm_caps);
@@ -965,7 +965,7 @@ p4_allocate_pmc(int cpu, int ri, struct pmc *pm,
if ((pevent = p4_find_event(pm->pm_event)) == NULL)
return (ESRCH);
- PMCDBG(MDP,ALL,2, "pevent={ev=%d,escrsel=0x%x,cccrsel=0x%x,isti=%d}",
+ PMCDBG4(MDP,ALL,2, "pevent={ev=%d,escrsel=0x%x,cccrsel=0x%x,isti=%d}",
pevent->pm_event, pevent->pm_escr_eventselect,
pevent->pm_cccr_select, pevent->pm_is_ti_event);
@@ -1105,7 +1105,7 @@ p4_allocate_pmc(int cpu, int ri, struct pmc *pm,
pm->pm_md.pm_p4.pm_p4_cccrvalue = cccrvalue;
pm->pm_md.pm_p4.pm_p4_escrvalue = escrvalue;
- PMCDBG(MDP,ALL,2, "p4-allocate cccrsel=0x%x cccrval=0x%x "
+ PMCDBG5(MDP,ALL,2, "p4-allocate cccrsel=0x%x cccrval=0x%x "
"escr=%d escrmsr=0x%x escrval=0x%x", pevent->pm_cccr_select,
cccrvalue, escr, pm->pm_md.pm_p4.pm_p4_escrmsr, escrvalue);
@@ -1127,7 +1127,7 @@ p4_release_pmc(int cpu, int ri, struct pmc *pm)
escr = pm->pm_md.pm_p4.pm_p4_escr;
- PMCDBG(MDP,REL,1, "p4-release cpu=%d ri=%d escr=%d", cpu, ri, escr);
+ PMCDBG3(MDP,REL,1, "p4-release cpu=%d ri=%d escr=%d", cpu, ri, escr);
if (PMC_IS_SYSTEM_MODE(PMC_TO_MODE(pm))) {
pc = p4_pcpu[P4_TO_HTT_PRIMARY(cpu)];
@@ -1171,7 +1171,7 @@ p4_start_pmc(int cpu, int ri)
KASSERT(pm != NULL,
("[p4,%d] starting cpu%d,pmc%d with null pmc", __LINE__, cpu, ri));
- PMCDBG(MDP,STA,1, "p4-start cpu=%d ri=%d", cpu, ri);
+ PMCDBG2(MDP,STA,1, "p4-start cpu=%d ri=%d", cpu, ri);
KASSERT(pd->pm_descr.pd_class == PMC_CLASS_P4,
("[p4,%d] wrong PMC class %d", __LINE__,
@@ -1283,9 +1283,10 @@ p4_start_pmc(int cpu, int ri)
mtx_unlock_spin(&pc->pc_mtx);
- PMCDBG(MDP,STA,2,"p4-start cpu=%d rc=%d ri=%d escr=%d "
- "escrmsr=0x%x escrvalue=0x%x cccr_config=0x%x v=%jx", cpu, rc,
- ri, pm->pm_md.pm_p4.pm_p4_escr, escrmsr, escrvalue,
+ PMCDBG6(MDP,STA,2,"p4-start cpu=%d rc=%d ri=%d escr=%d "
+ "escrmsr=0x%x escrvalue=0x%x", cpu, rc,
+ ri, pm->pm_md.pm_p4.pm_p4_escr, escrmsr, escrvalue);
+ PMCDBG2(MDP,STA,2,"cccr_config=0x%x v=%jx",
cccrvalue, P4_PCPU_HW_VALUE(pc,ri,cpu));
return (0);
@@ -1317,7 +1318,7 @@ p4_stop_pmc(int cpu, int ri)
KASSERT(pm != NULL,
("[p4,%d] null pmc for cpu%d, ri%d", __LINE__, cpu, ri));
- PMCDBG(MDP,STO,1, "p4-stop cpu=%d ri=%d", cpu, ri);
+ PMCDBG2(MDP,STO,1, "p4-stop cpu=%d ri=%d", cpu, ri);
if (PMC_IS_SYSTEM_MODE(PMC_TO_MODE(pm))) {
wrmsr(pd->pm_cccr_msr,
@@ -1385,9 +1386,9 @@ p4_stop_pmc(int cpu, int ri)
mtx_unlock_spin(&pc->pc_mtx);
- PMCDBG(MDP,STO,2, "p4-stop cpu=%d rc=%d ri=%d escrmsr=0x%x "
- "escrval=0x%x cccrval=0x%x v=%jx", cpu, rc, ri, escrmsr,
- escrvalue, cccrvalue, tmp);
+ PMCDBG5(MDP,STO,2, "p4-stop cpu=%d rc=%d ri=%d escrmsr=0x%x "
+ "escrval=0x%x", cpu, rc, ri, escrmsr, escrvalue);
+ PMCDBG2(MDP,STO,2, "cccrval=0x%x v=%jx", cccrvalue, tmp);
if (tmp < P4_PCPU_HW_VALUE(pc,ri,cpu)) /* 40 bit counter overflow */
tmp += (P4_PERFCTR_MASK + 1) - P4_PCPU_HW_VALUE(pc,ri,cpu);
@@ -1422,7 +1423,7 @@ p4_intr(int cpu, struct trapframe *tf)
struct pmc *pm;
pmc_value_t v;
- PMCDBG(MDP,INT, 1, "cpu=%d tf=0x%p um=%d", cpu, (void *) tf,
+ PMCDBG3(MDP,INT, 1, "cpu=%d tf=0x%p um=%d", cpu, (void *) tf,
TRAPF_USERMODE(tf));
pc = p4_pcpu[P4_TO_HTT_PRIMARY(cpu)];
@@ -1492,7 +1493,7 @@ p4_intr(int cpu, struct trapframe *tf)
v = rdmsr(P4_PERFCTR_MSR_FIRST + ri);
- PMCDBG(MDP,INT, 2, "ri=%d v=%jx", ri, v);
+ PMCDBG2(MDP,INT, 2, "ri=%d v=%jx", ri, v);
/* Stop the counter, and reset the overflow bit */
cccrval &= ~(P4_CCCR_OVF | P4_CCCR_ENABLE);
@@ -1568,7 +1569,7 @@ p4_describe(int cpu, int ri, struct pmc_info *pi,
KASSERT(ri >= 0 && ri < P4_NPMCS,
("[p4,%d] row-index %d out of range", __LINE__, ri));
- PMCDBG(MDP,OPS,1,"p4-describe cpu=%d ri=%d", cpu, ri);
+ PMCDBG2(MDP,OPS,1,"p4-describe cpu=%d ri=%d", cpu, ri);
if (P4_CPU_IS_HTT_SECONDARY(cpu))
return (EINVAL);
@@ -1604,7 +1605,7 @@ p4_get_msr(int ri, uint32_t *msr)
*msr = p4_pmcdesc[ri].pm_pmc_msr - P4_PERFCTR_MSR_FIRST;
- PMCDBG(MDP,OPS, 1, "ri=%d getmsr=0x%x", ri, *msr);
+ PMCDBG2(MDP,OPS, 1, "ri=%d getmsr=0x%x", ri, *msr);
return 0;
}
@@ -1620,7 +1621,7 @@ pmc_p4_initialize(struct pmc_mdep *md, int ncpus)
KASSERT(cpu_vendor_id == CPU_VENDOR_INTEL,
("[p4,%d] Initializing non-intel processor", __LINE__));
- PMCDBG(MDP,INI,1, "%s", "p4-initialize");
+ PMCDBG0(MDP,INI,1, "p4-initialize");
/* Allocate space for pointers to per-cpu descriptors. */
p4_pcpu = malloc(sizeof(*p4_pcpu) * ncpus, M_PMC, M_ZERO | M_WAITOK);
diff --git a/sys/dev/hwpmc/hwpmc_ppc970.c b/sys/dev/hwpmc/hwpmc_ppc970.c
index f477be3..1a263f3 100644
--- a/sys/dev/hwpmc/hwpmc_ppc970.c
+++ b/sys/dev/hwpmc/hwpmc_ppc970.c
@@ -342,7 +342,7 @@ ppc970_config_pmc(int cpu, int ri, struct pmc *pm)
{
struct pmc_hw *phw;
- PMCDBG(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm);
+ PMCDBG3(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm);
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[powerpc,%d] illegal CPU value %d", __LINE__, cpu));
@@ -445,7 +445,7 @@ ppc970_read_pmc(int cpu, int ri, pmc_value_t *v)
ri));
tmp = ppc970_pmcn_read(ri);
- PMCDBG(MDP,REA,2,"ppc-read id=%d -> %jd", ri, tmp);
+ PMCDBG2(MDP,REA,2,"ppc-read id=%d -> %jd", ri, tmp);
if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
*v = POWERPC_PERFCTR_VALUE_TO_RELOAD_COUNT(tmp);
else
@@ -469,7 +469,7 @@ ppc970_write_pmc(int cpu, int ri, pmc_value_t v)
if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
v = POWERPC_RELOAD_COUNT_TO_PERFCTR_VALUE(v);
- PMCDBG(MDP,WRI,1,"powerpc-write cpu=%d ri=%d v=%jx", cpu, ri, v);
+ PMCDBG3(MDP,WRI,1,"powerpc-write cpu=%d ri=%d v=%jx", cpu, ri, v);
ppc970_pmcn_write(ri, v);
@@ -487,7 +487,7 @@ ppc970_intr(int cpu, struct trapframe *tf)
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[powerpc,%d] out of range CPU %d", __LINE__, cpu));
- PMCDBG(MDP,INT,1, "cpu=%d tf=%p um=%d", cpu, (void *) tf,
+ PMCDBG3(MDP,INT,1, "cpu=%d tf=%p um=%d", cpu, (void *) tf,
TRAPF_USERMODE(tf));
retval = 0;
@@ -546,7 +546,7 @@ ppc970_pcpu_init(struct pmc_mdep *md, int cpu)
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[powerpc,%d] wrong cpu number %d", __LINE__, cpu));
- PMCDBG(MDP,INI,1,"powerpc-init cpu=%d", cpu);
+ PMCDBG1(MDP,INI,1,"powerpc-init cpu=%d", cpu);
powerpc_pcpu[cpu] = pac = malloc(sizeof(struct powerpc_cpu), M_PMC,
M_WAITOK|M_ZERO);
@@ -632,7 +632,7 @@ ppc970_allocate_pmc(int cpu, int ri, struct pmc *pm,
pm->pm_md.pm_powerpc.pm_powerpc_evsel = config;
- PMCDBG(MDP,ALL,2,"powerpc-allocate ri=%d -> config=0x%x", ri, config);
+ PMCDBG2(MDP,ALL,2,"powerpc-allocate ri=%d -> config=0x%x", ri, config);
return 0;
}
diff --git a/sys/dev/hwpmc/hwpmc_ppro.c b/sys/dev/hwpmc/hwpmc_ppro.c
index e99bb30..9d983fa 100644
--- a/sys/dev/hwpmc/hwpmc_ppro.c
+++ b/sys/dev/hwpmc/hwpmc_ppro.c
@@ -339,7 +339,7 @@ p6_pcpu_init(struct pmc_mdep *md, int cpu)
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[p6,%d] bad cpu %d", __LINE__, cpu));
- PMCDBG(MDP,INI,0,"p6-init cpu=%d", cpu);
+ PMCDBG1(MDP,INI,0,"p6-init cpu=%d", cpu);
p6c = malloc(sizeof (struct p6_cpu), M_PMC, M_WAITOK|M_ZERO);
pc = pmc_pcpu[cpu];
@@ -371,7 +371,7 @@ p6_pcpu_fini(struct pmc_mdep *md, int cpu)
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[p6,%d] bad cpu %d", __LINE__, cpu));
- PMCDBG(MDP,INI,0,"p6-cleanup cpu=%d", cpu);
+ PMCDBG1(MDP,INI,0,"p6-cleanup cpu=%d", cpu);
p6c = p6_pcpu[cpu];
p6_pcpu[cpu] = NULL;
@@ -412,7 +412,7 @@ p6_read_pmc(int cpu, int ri, pmc_value_t *v)
else
*v = tmp;
- PMCDBG(MDP,REA,1, "p6-read cpu=%d ri=%d msr=0x%x -> v=%jx", cpu, ri,
+ PMCDBG4(MDP,REA,1, "p6-read cpu=%d ri=%d msr=0x%x -> v=%jx", cpu, ri,
pd->pm_pmc_msr, *v);
return (0);
@@ -435,7 +435,7 @@ p6_write_pmc(int cpu, int ri, pmc_value_t v)
KASSERT(pm,
("[p6,%d] cpu %d ri %d pmc not configured", __LINE__, cpu, ri));
- PMCDBG(MDP,WRI,1, "p6-write cpu=%d ri=%d msr=0x%x v=%jx", cpu, ri,
+ PMCDBG4(MDP,WRI,1, "p6-write cpu=%d ri=%d msr=0x%x v=%jx", cpu, ri,
pd->pm_pmc_msr, v);
if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
@@ -455,7 +455,7 @@ p6_config_pmc(int cpu, int ri, struct pmc *pm)
KASSERT(ri >= 0 && ri < P6_NPMCS,
("[p6,%d] illegal row-index %d", __LINE__, ri));
- PMCDBG(MDP,CFG,1, "p6-config cpu=%d ri=%d pm=%p", cpu, ri, pm);
+ PMCDBG3(MDP,CFG,1, "p6-config cpu=%d ri=%d pm=%p", cpu, ri, pm);
KASSERT(p6_pcpu[cpu] != NULL, ("[p6,%d] null per-cpu %d", __LINE__,
cpu));
@@ -508,7 +508,7 @@ p6_allocate_pmc(int cpu, int ri, struct pmc *pm,
pd = &p6_pmcdesc[ri];
- PMCDBG(MDP,ALL,1, "p6-allocate ri=%d class=%d pmccaps=0x%x "
+ PMCDBG4(MDP,ALL,1, "p6-allocate ri=%d class=%d pmccaps=0x%x "
"reqcaps=0x%x", ri, pd->pm_descr.pd_class, pd->pm_descr.pd_caps,
pm->pm_caps);
@@ -579,7 +579,7 @@ p6_allocate_pmc(int cpu, int ri, struct pmc *pm,
pm->pm_md.pm_ppro.pm_ppro_evsel = config;
- PMCDBG(MDP,ALL,2, "p6-allocate config=0x%x", config);
+ PMCDBG1(MDP,ALL,2, "p6-allocate config=0x%x", config);
return (0);
}
@@ -589,7 +589,7 @@ p6_release_pmc(int cpu, int ri, struct pmc *pm)
{
(void) pm;
- PMCDBG(MDP,REL,1, "p6-release cpu=%d ri=%d pm=%p", cpu, ri, pm);
+ PMCDBG3(MDP,REL,1, "p6-release cpu=%d ri=%d pm=%p", cpu, ri, pm);
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[p6,%d] illegal CPU value %d", __LINE__, cpu));
@@ -623,11 +623,11 @@ p6_start_pmc(int cpu, int ri)
("[p6,%d] starting cpu%d,ri%d with no pmc configured",
__LINE__, cpu, ri));
- PMCDBG(MDP,STA,1, "p6-start cpu=%d ri=%d", cpu, ri);
+ PMCDBG2(MDP,STA,1, "p6-start cpu=%d ri=%d", cpu, ri);
config = pm->pm_md.pm_ppro.pm_ppro_evsel;
- PMCDBG(MDP,STA,2, "p6-start/2 cpu=%d ri=%d evselmsr=0x%x config=0x%x",
+ PMCDBG4(MDP,STA,2, "p6-start/2 cpu=%d ri=%d evselmsr=0x%x config=0x%x",
cpu, ri, pd->pm_evsel_msr, config);
P6_MARK_STARTED(pc, ri);
@@ -658,14 +658,14 @@ p6_stop_pmc(int cpu, int ri)
("[p6,%d] cpu%d ri%d no configured PMC to stop", __LINE__,
cpu, ri));
- PMCDBG(MDP,STO,1, "p6-stop cpu=%d ri=%d", cpu, ri);
+ PMCDBG2(MDP,STO,1, "p6-stop cpu=%d ri=%d", cpu, ri);
wrmsr(pd->pm_evsel_msr, 0); /* stop hw */
P6_MARK_STOPPED(pc, ri); /* update software state */
P6_SYNC_CTR_STATE(pc); /* restart CTR1 if need be */
- PMCDBG(MDP,STO,2, "p6-stop/2 cpu=%d ri=%d", cpu, ri);
+ PMCDBG2(MDP,STO,2, "p6-stop/2 cpu=%d ri=%d", cpu, ri);
return (0);
}
@@ -788,7 +788,7 @@ pmc_p6_initialize(struct pmc_mdep *md, int ncpus)
KASSERT(cpu_vendor_id == CPU_VENDOR_INTEL,
("[p6,%d] Initializing non-intel processor", __LINE__));
- PMCDBG(MDP,INI,1, "%s", "p6-initialize");
+ PMCDBG0(MDP,INI,1, "p6-initialize");
/* Allocate space for pointers to per-cpu descriptors. */
p6_pcpu = malloc(sizeof(struct p6_cpu **) * ncpus, M_PMC,
diff --git a/sys/dev/hwpmc/hwpmc_soft.c b/sys/dev/hwpmc/hwpmc_soft.c
index 7a585eb..fe143ad 100644
--- a/sys/dev/hwpmc/hwpmc_soft.c
+++ b/sys/dev/hwpmc/hwpmc_soft.c
@@ -136,7 +136,7 @@ soft_config_pmc(int cpu, int ri, struct pmc *pm)
{
struct pmc_hw *phw;
- PMCDBG(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm);
+ PMCDBG3(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm);
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[soft,%d] illegal CPU value %d", __LINE__, cpu));
@@ -276,7 +276,7 @@ soft_read_pmc(int cpu, int ri, pmc_value_t *v)
KASSERT(pm != NULL,
("[soft,%d] no owner for PHW [cpu%d,pmc%d]", __LINE__, cpu, ri));
- PMCDBG(MDP,REA,1,"soft-read id=%d", ri);
+ PMCDBG1(MDP,REA,1,"soft-read id=%d", ri);
*v = soft_pcpu[cpu]->soft_values[ri];
@@ -300,7 +300,7 @@ soft_write_pmc(int cpu, int ri, pmc_value_t v)
KASSERT(pm,
("[soft,%d] cpu %d ri %d pmc not configured", __LINE__, cpu, ri));
- PMCDBG(MDP,WRI,1, "soft-write cpu=%d ri=%d v=%jx", cpu, ri, v);
+ PMCDBG3(MDP,WRI,1, "soft-write cpu=%d ri=%d v=%jx", cpu, ri, v);
soft_pcpu[cpu]->soft_values[ri] = v;
diff --git a/sys/dev/hwpmc/hwpmc_tsc.c b/sys/dev/hwpmc/hwpmc_tsc.c
index 237b7a1..5eb6907 100644
--- a/sys/dev/hwpmc/hwpmc_tsc.c
+++ b/sys/dev/hwpmc/hwpmc_tsc.c
@@ -99,7 +99,7 @@ tsc_config_pmc(int cpu, int ri, struct pmc *pm)
{
struct pmc_hw *phw;
- PMCDBG(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm);
+ PMCDBG3(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm);
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[tsc,%d] illegal CPU value %d", __LINE__, cpu));
@@ -253,7 +253,7 @@ tsc_read_pmc(int cpu, int ri, pmc_value_t *v)
KASSERT(mode == PMC_MODE_SC,
("[tsc,%d] illegal pmc mode %d", __LINE__, mode));
- PMCDBG(MDP,REA,1,"tsc-read id=%d", ri);
+ PMCDBG1(MDP,REA,1,"tsc-read id=%d", ri);
*v = rdtsc();
diff --git a/sys/dev/hwpmc/hwpmc_uncore.c b/sys/dev/hwpmc/hwpmc_uncore.c
index 6a30eb0..2b24b33e 100644
--- a/sys/dev/hwpmc/hwpmc_uncore.c
+++ b/sys/dev/hwpmc/hwpmc_uncore.c
@@ -101,7 +101,7 @@ uncore_pcpu_init(struct pmc_mdep *md, int cpu)
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[ucf,%d] insane cpu number %d", __LINE__, cpu));
- PMCDBG(MDP,INI,1,"uncore-init cpu=%d", cpu);
+ PMCDBG1(MDP,INI,1,"uncore-init cpu=%d", cpu);
uncore_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCP].pcd_ri;
npmc = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCP].pcd_num;
@@ -137,7 +137,7 @@ uncore_pcpu_fini(struct pmc_mdep *md, int cpu)
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[uncore,%d] insane cpu number (%d)", __LINE__, cpu));
- PMCDBG(MDP,INI,1,"uncore-pcpu-fini cpu=%d", cpu);
+ PMCDBG1(MDP,INI,1,"uncore-pcpu-fini cpu=%d", cpu);
if ((cc = uncore_pcpu[cpu]) == NULL)
return (0);
@@ -193,7 +193,7 @@ ucf_allocate_pmc(int cpu, int ri, struct pmc *pm,
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[uncore,%d] illegal CPU %d", __LINE__, cpu));
- PMCDBG(MDP,ALL,1, "ucf-allocate ri=%d reqcaps=0x%x", ri, pm->pm_caps);
+ PMCDBG2(MDP,ALL,1, "ucf-allocate ri=%d reqcaps=0x%x", ri, pm->pm_caps);
if (ri < 0 || ri > uncore_ucf_npmc)
return (EINVAL);
@@ -212,7 +212,7 @@ ucf_allocate_pmc(int cpu, int ri, struct pmc *pm,
pm->pm_md.pm_ucf.pm_ucf_ctrl = (flags << (ri * 4));
- PMCDBG(MDP,ALL,2, "ucf-allocate config=0x%jx",
+ PMCDBG1(MDP,ALL,2, "ucf-allocate config=0x%jx",
(uintmax_t) pm->pm_md.pm_ucf.pm_ucf_ctrl);
return (0);
@@ -227,7 +227,7 @@ ucf_config_pmc(int cpu, int ri, struct pmc *pm)
KASSERT(ri >= 0 && ri < uncore_ucf_npmc,
("[uncore,%d] illegal row-index %d", __LINE__, ri));
- PMCDBG(MDP,CFG,1, "ucf-config cpu=%d ri=%d pm=%p", cpu, ri, pm);
+ PMCDBG3(MDP,CFG,1, "ucf-config cpu=%d ri=%d pm=%p", cpu, ri, pm);
KASSERT(uncore_pcpu[cpu] != NULL, ("[uncore,%d] null per-cpu %d", __LINE__,
cpu));
@@ -296,7 +296,7 @@ ucf_read_pmc(int cpu, int ri, pmc_value_t *v)
else
*v = tmp;
- PMCDBG(MDP,REA,1, "ucf-read cpu=%d ri=%d -> v=%jx", cpu, ri, *v);
+ PMCDBG3(MDP,REA,1, "ucf-read cpu=%d ri=%d -> v=%jx", cpu, ri, *v);
return (0);
}
@@ -304,7 +304,7 @@ ucf_read_pmc(int cpu, int ri, pmc_value_t *v)
static int
ucf_release_pmc(int cpu, int ri, struct pmc *pmc)
{
- PMCDBG(MDP,REL,1, "ucf-release cpu=%d ri=%d pm=%p", cpu, ri, pmc);
+ PMCDBG3(MDP,REL,1, "ucf-release cpu=%d ri=%d pm=%p", cpu, ri, pmc);
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[uncore,%d] illegal CPU value %d", __LINE__, cpu));
@@ -328,7 +328,7 @@ ucf_start_pmc(int cpu, int ri)
KASSERT(ri >= 0 && ri < uncore_ucf_npmc,
("[uncore,%d] illegal row-index %d", __LINE__, ri));
- PMCDBG(MDP,STA,1,"ucf-start cpu=%d ri=%d", cpu, ri);
+ PMCDBG2(MDP,STA,1,"ucf-start cpu=%d ri=%d", cpu, ri);
ucfc = uncore_pcpu[cpu];
pm = ucfc->pc_uncorepmcs[ri + uncore_ucf_ri].phw_pmc;
@@ -343,7 +343,7 @@ ucf_start_pmc(int cpu, int ri)
wrmsr(UC_GLOBAL_CTRL, ucfc->pc_globalctrl);
} while (ucfc->pc_resync != 0);
- PMCDBG(MDP,STA,1,"ucfctrl=%x(%x) globalctrl=%jx(%jx)",
+ PMCDBG4(MDP,STA,1,"ucfctrl=%x(%x) globalctrl=%jx(%jx)",
ucfc->pc_ucfctrl, (uint32_t) rdmsr(UCF_CTRL),
ucfc->pc_globalctrl, rdmsr(UC_GLOBAL_CTRL));
@@ -356,7 +356,7 @@ ucf_stop_pmc(int cpu, int ri)
uint32_t fc;
struct uncore_cpu *ucfc;
- PMCDBG(MDP,STO,1,"ucf-stop cpu=%d ri=%d", cpu, ri);
+ PMCDBG2(MDP,STO,1,"ucf-stop cpu=%d ri=%d", cpu, ri);
ucfc = uncore_pcpu[cpu];
@@ -369,7 +369,7 @@ ucf_stop_pmc(int cpu, int ri)
ucfc->pc_ucfctrl &= ~fc;
- PMCDBG(MDP,STO,1,"ucf-stop ucfctrl=%x", ucfc->pc_ucfctrl);
+ PMCDBG1(MDP,STO,1,"ucf-stop ucfctrl=%x", ucfc->pc_ucfctrl);
wrmsr(UCF_CTRL, ucfc->pc_ucfctrl);
do {
@@ -378,7 +378,7 @@ ucf_stop_pmc(int cpu, int ri)
wrmsr(UC_GLOBAL_CTRL, ucfc->pc_globalctrl);
} while (ucfc->pc_resync != 0);
- PMCDBG(MDP,STO,1,"ucfctrl=%x(%x) globalctrl=%jx(%jx)",
+ PMCDBG4(MDP,STO,1,"ucfctrl=%x(%x) globalctrl=%jx(%jx)",
ucfc->pc_ucfctrl, (uint32_t) rdmsr(UCF_CTRL),
ucfc->pc_globalctrl, rdmsr(UC_GLOBAL_CTRL));
@@ -409,7 +409,7 @@ ucf_write_pmc(int cpu, int ri, pmc_value_t v)
wrmsr(UCF_CTR0 + ri, v);
wrmsr(UCF_CTRL, cc->pc_ucfctrl);
- PMCDBG(MDP,WRI,1, "ucf-write cpu=%d ri=%d v=%jx ucfctrl=%jx ",
+ PMCDBG4(MDP,WRI,1, "ucf-write cpu=%d ri=%d v=%jx ucfctrl=%jx ",
cpu, ri, v, (uintmax_t) rdmsr(UCF_CTRL));
return (0);
@@ -423,7 +423,7 @@ ucf_initialize(struct pmc_mdep *md, int maxcpu, int npmc, int pmcwidth)
KASSERT(md != NULL, ("[ucf,%d] md is NULL", __LINE__));
- PMCDBG(MDP,INI,1, "%s", "ucf-initialize");
+ PMCDBG0(MDP,INI,1, "ucf-initialize");
pcd = &md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCF];
@@ -933,7 +933,7 @@ ucp_config_pmc(int cpu, int ri, struct pmc *pm)
KASSERT(ri >= 0 && ri < uncore_ucp_npmc,
("[uncore,%d] illegal row-index %d", __LINE__, ri));
- PMCDBG(MDP,CFG,1, "ucp-config cpu=%d ri=%d pm=%p", cpu, ri, pm);
+ PMCDBG3(MDP,CFG,1, "ucp-config cpu=%d ri=%d pm=%p", cpu, ri, pm);
KASSERT(uncore_pcpu[cpu] != NULL, ("[uncore,%d] null per-cpu %d", __LINE__,
cpu));
@@ -1001,7 +1001,7 @@ ucp_read_pmc(int cpu, int ri, pmc_value_t *v)
else
*v = tmp;
- PMCDBG(MDP,REA,1, "ucp-read cpu=%d ri=%d msr=0x%x -> v=%jx", cpu, ri,
+ PMCDBG4(MDP,REA,1, "ucp-read cpu=%d ri=%d msr=0x%x -> v=%jx", cpu, ri,
ri, *v);
return (0);
@@ -1012,7 +1012,7 @@ ucp_release_pmc(int cpu, int ri, struct pmc *pm)
{
(void) pm;
- PMCDBG(MDP,REL,1, "ucp-release cpu=%d ri=%d pm=%p", cpu, ri,
+ PMCDBG3(MDP,REL,1, "ucp-release cpu=%d ri=%d pm=%p", cpu, ri,
pm);
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
@@ -1045,11 +1045,11 @@ ucp_start_pmc(int cpu, int ri)
("[uncore,%d] starting cpu%d,ri%d with no pmc configured",
__LINE__, cpu, ri));
- PMCDBG(MDP,STA,1, "ucp-start cpu=%d ri=%d", cpu, ri);
+ PMCDBG2(MDP,STA,1, "ucp-start cpu=%d ri=%d", cpu, ri);
evsel = pm->pm_md.pm_ucp.pm_ucp_evsel;
- PMCDBG(MDP,STA,2,
+ PMCDBG4(MDP,STA,2,
"ucp-start/2 cpu=%d ri=%d evselmsr=0x%x evsel=0x%x",
cpu, ri, SELECTSEL(uncore_cputype) + ri, evsel);
@@ -1104,7 +1104,7 @@ ucp_stop_pmc(int cpu, int ri)
("[uncore,%d] cpu%d ri%d no configured PMC to stop", __LINE__,
cpu, ri));
- PMCDBG(MDP,STO,1, "ucp-stop cpu=%d ri=%d", cpu, ri);
+ PMCDBG2(MDP,STO,1, "ucp-stop cpu=%d ri=%d", cpu, ri);
/* stop hw. */
wrmsr(SELECTSEL(uncore_cputype) + ri, 0);
@@ -1136,7 +1136,7 @@ ucp_write_pmc(int cpu, int ri, pmc_value_t v)
("[uncore,%d] cpu%d ri%d no configured PMC to stop", __LINE__,
cpu, ri));
- PMCDBG(MDP,WRI,1, "ucp-write cpu=%d ri=%d msr=0x%x v=%jx", cpu, ri,
+ PMCDBG4(MDP,WRI,1, "ucp-write cpu=%d ri=%d msr=0x%x v=%jx", cpu, ri,
UCP_PMC0 + ri, v);
if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
@@ -1160,7 +1160,7 @@ ucp_initialize(struct pmc_mdep *md, int maxcpu, int npmc, int pmcwidth)
KASSERT(md != NULL, ("[ucp,%d] md is NULL", __LINE__));
- PMCDBG(MDP,INI,1, "%s", "ucp-initialize");
+ PMCDBG0(MDP,INI,1, "ucp-initialize");
pcd = &md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCP];
@@ -1213,7 +1213,7 @@ pmc_uncore_initialize(struct pmc_mdep *md, int maxcpu)
ucf_initialize(md, maxcpu, uncore_ucf_npmc, uncore_ucf_width);
uncore_pmcmask |= ((1ULL << uncore_ucf_npmc) - 1) << SELECTOFF(uncore_cputype);
- PMCDBG(MDP,INI,1,"uncore-init pmcmask=0x%jx ucfri=%d", uncore_pmcmask,
+ PMCDBG2(MDP,INI,1,"uncore-init pmcmask=0x%jx ucfri=%d", uncore_pmcmask,
uncore_ucf_ri);
uncore_pcpu = malloc(sizeof(*uncore_pcpu) * maxcpu, M_PMC,
@@ -1225,7 +1225,7 @@ pmc_uncore_initialize(struct pmc_mdep *md, int maxcpu)
void
pmc_uncore_finalize(struct pmc_mdep *md)
{
- PMCDBG(MDP,INI,1, "%s", "uncore-finalize");
+ PMCDBG0(MDP,INI,1, "uncore-finalize");
free(uncore_pcpu, M_PMC);
uncore_pcpu = NULL;
diff --git a/sys/dev/hwpmc/hwpmc_xscale.c b/sys/dev/hwpmc/hwpmc_xscale.c
index 9b73337..e5df8d0 100644
--- a/sys/dev/hwpmc/hwpmc_xscale.c
+++ b/sys/dev/hwpmc/hwpmc_xscale.c
@@ -277,7 +277,7 @@ xscale_allocate_pmc(int cpu, int ri, struct pmc *pm,
return EINVAL;
pm->pm_md.pm_xscale.pm_xscale_evsel = config;
- PMCDBG(MDP,ALL,2,"xscale-allocate ri=%d -> config=0x%x", ri, config);
+ PMCDBG2(MDP,ALL,2,"xscale-allocate ri=%d -> config=0x%x", ri, config);
return 0;
}
@@ -296,7 +296,7 @@ xscale_read_pmc(int cpu, int ri, pmc_value_t *v)
pm = xscale_pcpu[cpu]->pc_xscalepmcs[ri].phw_pmc;
tmp = xscale_pmcn_read(ri);
- PMCDBG(MDP,REA,2,"xscale-read id=%d -> %jd", ri, tmp);
+ PMCDBG2(MDP,REA,2,"xscale-read id=%d -> %jd", ri, tmp);
if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
*v = XSCALE_PERFCTR_VALUE_TO_RELOAD_COUNT(tmp);
else
@@ -320,7 +320,7 @@ xscale_write_pmc(int cpu, int ri, pmc_value_t v)
if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
v = XSCALE_RELOAD_COUNT_TO_PERFCTR_VALUE(v);
- PMCDBG(MDP,WRI,1,"xscale-write cpu=%d ri=%d v=%jx", cpu, ri, v);
+ PMCDBG3(MDP,WRI,1,"xscale-write cpu=%d ri=%d v=%jx", cpu, ri, v);
xscale_pmcn_write(ri, v);
@@ -332,7 +332,7 @@ xscale_config_pmc(int cpu, int ri, struct pmc *pm)
{
struct pmc_hw *phw;
- PMCDBG(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm);
+ PMCDBG3(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm);
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[xscale,%d] illegal CPU value %d", __LINE__, cpu));
@@ -568,7 +568,7 @@ xscale_pcpu_init(struct pmc_mdep *md, int cpu)
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[xscale,%d] wrong cpu number %d", __LINE__, cpu));
- PMCDBG(MDP,INI,1,"xscale-init cpu=%d", cpu);
+ PMCDBG1(MDP,INI,1,"xscale-init cpu=%d", cpu);
xscale_pcpu[cpu] = pac = malloc(sizeof(struct xscale_cpu), M_PMC,
M_WAITOK|M_ZERO);
@@ -628,7 +628,7 @@ pmc_xscale_initialize()
printf("%s: unknown XScale core generation\n", __func__);
return (NULL);
}
- PMCDBG(MDP,INI,1,"xscale-init npmcs=%d", xscale_npmcs);
+ PMCDBG1(MDP,INI,1,"xscale-init npmcs=%d", xscale_npmcs);
/*
* Allocate space for pointers to PMC HW descriptors and for
diff --git a/sys/dev/iicbus/iicbus.c b/sys/dev/iicbus/iicbus.c
index dc56760..150eecd 100644
--- a/sys/dev/iicbus/iicbus.c
+++ b/sys/dev/iicbus/iicbus.c
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/mutex.h>
+#include <sys/rman.h>
#include <sys/sysctl.h>
#include <sys/bus.h>
@@ -147,6 +148,7 @@ iicbus_print_child(device_t dev, device_t child)
retval += bus_print_child_header(dev, child);
if (devi->addr != 0)
retval += printf(" at addr %#x", devi->addr);
+ resource_list_print_type(&devi->rl, "irq", SYS_RES_IRQ, "%ld");
retval += bus_print_child_footer(dev, child);
return (retval);
@@ -157,9 +159,9 @@ iicbus_probe_nomatch(device_t bus, device_t child)
{
struct iicbus_ivar *devi = IICBUS_IVAR(child);
- device_printf(bus, "<unknown card>");
- printf(" at addr %#x\n", devi->addr);
- return;
+ device_printf(bus, "<unknown card> at addr %#x", devi->addr);
+ resource_list_print_type(&devi->rl, "irq", SYS_RES_IRQ, "%ld");
+ printf("\n");
}
static int
@@ -209,6 +211,7 @@ iicbus_add_child(device_t dev, u_int order, const char *name, int unit)
device_delete_child(dev, child);
return (0);
}
+ resource_list_init(&devi->rl);
device_set_ivars(child, devi);
return (child);
}
@@ -217,11 +220,77 @@ static void
iicbus_hinted_child(device_t bus, const char *dname, int dunit)
{
device_t child;
+ int irq;
struct iicbus_ivar *devi;
child = BUS_ADD_CHILD(bus, 0, dname, dunit);
devi = IICBUS_IVAR(child);
resource_int_value(dname, dunit, "addr", &devi->addr);
+ if (resource_int_value(dname, dunit, "irq", &irq) == 0) {
+ if (bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1) != 0)
+ device_printf(bus,
+ "warning: bus_set_resource() failed\n");
+ }
+}
+
+static int
+iicbus_set_resource(device_t dev, device_t child, int type, int rid,
+ u_long start, u_long count)
+{
+ struct iicbus_ivar *devi;
+ struct resource_list_entry *rle;
+
+ devi = IICBUS_IVAR(child);
+ rle = resource_list_add(&devi->rl, type, rid, start,
+ start + count - 1, count);
+ if (rle == NULL)
+ return (ENXIO);
+
+ return (0);
+}
+
+static struct resource *
+iicbus_alloc_resource(device_t bus, device_t child, int type, int *rid,
+ u_long start, u_long end, u_long count, u_int flags)
+{
+ struct resource_list *rl;
+ struct resource_list_entry *rle;
+
+ /* Only IRQ resources are supported. */
+ if (type != SYS_RES_IRQ)
+ return (NULL);
+
+ /*
+ * Request for the default allocation with a given rid: use resource
+ * list stored in the local device info.
+ */
+ if ((start == 0UL) && (end == ~0UL)) {
+ rl = BUS_GET_RESOURCE_LIST(bus, child);
+ if (rl == NULL)
+ return (NULL);
+ rle = resource_list_find(rl, type, *rid);
+ if (rle == NULL) {
+ if (bootverbose)
+ device_printf(bus, "no default resources for "
+ "rid = %d, type = %d\n", *rid, type);
+ return (NULL);
+ }
+ start = rle->start;
+ end = rle->end;
+ count = rle->count;
+ }
+
+ return (bus_generic_alloc_resource(bus, child, type, rid, start, end,
+ count, flags));
+}
+
+static struct resource_list *
+iicbus_get_resource_list(device_t bus __unused, device_t child)
+{
+ struct iicbus_ivar *devi;
+
+ devi = IICBUS_IVAR(child);
+ return (&devi->rl);
}
int
@@ -291,14 +360,24 @@ iicbus_get_frequency(device_t dev, u_char speed)
}
static device_method_t iicbus_methods[] = {
- /* device interface */
- DEVMETHOD(device_probe, iicbus_probe),
- DEVMETHOD(device_attach, iicbus_attach),
- DEVMETHOD(device_detach, iicbus_detach),
-
- /* bus interface */
- DEVMETHOD(bus_add_child, iicbus_add_child),
- DEVMETHOD(bus_print_child, iicbus_print_child),
+ /* device interface */
+ DEVMETHOD(device_probe, iicbus_probe),
+ DEVMETHOD(device_attach, iicbus_attach),
+ DEVMETHOD(device_detach, iicbus_detach),
+
+ /* bus interface */
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+ DEVMETHOD(bus_release_resource, bus_generic_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource),
+ DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
+ DEVMETHOD(bus_alloc_resource, iicbus_alloc_resource),
+ DEVMETHOD(bus_get_resource_list, iicbus_get_resource_list),
+ DEVMETHOD(bus_set_resource, iicbus_set_resource),
+ DEVMETHOD(bus_add_child, iicbus_add_child),
+ DEVMETHOD(bus_print_child, iicbus_print_child),
DEVMETHOD(bus_probe_nomatch, iicbus_probe_nomatch),
DEVMETHOD(bus_read_ivar, iicbus_read_ivar),
DEVMETHOD(bus_child_pnpinfo_str, iicbus_child_pnpinfo_str),
@@ -322,4 +401,3 @@ devclass_t iicbus_devclass;
MODULE_VERSION(iicbus, IICBUS_MODVER);
DRIVER_MODULE(iicbus, iichb, iicbus_driver, iicbus_devclass, 0, 0);
-
diff --git a/sys/dev/iicbus/iicbus.h b/sys/dev/iicbus/iicbus.h
index b5905ad..1085319 100644
--- a/sys/dev/iicbus/iicbus.h
+++ b/sys/dev/iicbus/iicbus.h
@@ -50,6 +50,7 @@ struct iicbus_softc
struct iicbus_ivar
{
uint32_t addr;
+ struct resource_list rl;
bool nostop;
};
diff --git a/sys/dev/ofw/ofw_iicbus.c b/sys/dev/ofw/ofw_iicbus.c
index f6d1be5..e51aef1 100644
--- a/sys/dev/ofw/ofw_iicbus.c
+++ b/sys/dev/ofw/ofw_iicbus.c
@@ -50,6 +50,8 @@ static device_t ofw_iicbus_add_child(device_t dev, u_int order,
const char *name, int unit);
static const struct ofw_bus_devinfo *ofw_iicbus_get_devinfo(device_t bus,
device_t dev);
+static struct resource_list *ofw_iicbus_get_resource_list(device_t bus,
+ device_t child);
static device_method_t ofw_iicbus_methods[] = {
/* Device interface */
@@ -57,6 +59,7 @@ static device_method_t ofw_iicbus_methods[] = {
DEVMETHOD(device_attach, ofw_iicbus_attach),
/* Bus interface */
+ DEVMETHOD(bus_get_resource_list, ofw_iicbus_get_resource_list),
DEVMETHOD(bus_child_pnpinfo_str, ofw_bus_gen_child_pnpinfo_str),
DEVMETHOD(bus_add_child, ofw_iicbus_add_child),
@@ -72,7 +75,7 @@ static device_method_t ofw_iicbus_methods[] = {
};
struct ofw_iicbus_devinfo {
- struct iicbus_ivar opd_dinfo;
+ struct iicbus_ivar opd_dinfo; /* Must be the first. */
struct ofw_bus_devinfo opd_obdinfo;
};
@@ -153,7 +156,10 @@ ofw_iicbus_attach(device_t dev)
free(dinfo, M_DEVBUF);
continue;
}
+
childdev = device_add_child(dev, NULL, -1);
+ resource_list_init(&dinfo->opd_dinfo.rl);
+ ofw_bus_intr_to_rl(childdev, child, &dinfo->opd_dinfo.rl);
device_set_ivars(childdev, dinfo);
}
@@ -199,3 +205,12 @@ ofw_iicbus_get_devinfo(device_t bus, device_t dev)
dinfo = device_get_ivars(dev);
return (&dinfo->opd_obdinfo);
}
+
+static struct resource_list *
+ofw_iicbus_get_resource_list(device_t bus __unused, device_t child)
+{
+ struct ofw_iicbus_devinfo *devi;
+
+ devi = device_get_ivars(child);
+ return (&devi->opd_dinfo.rl);
+}
diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c
index fbf49f6..83ec6c1 100644
--- a/sys/dev/sound/pcm/channel.c
+++ b/sys/dev/sound/pcm/channel.c
@@ -1020,32 +1020,17 @@ static const struct {
{ NULL, NULL, NULL, 0 }
};
-static const struct {
- char *name, *alias1, *alias2;
- int matrix_id;
-} matrix_id_tab[] = {
- { "1.0", "1", "mono", SND_CHN_MATRIX_1_0 },
- { "2.0", "2", "stereo", SND_CHN_MATRIX_2_0 },
- { "2.1", NULL, NULL, SND_CHN_MATRIX_2_1 },
- { "3.0", "3", NULL, SND_CHN_MATRIX_3_0 },
- { "3.1", NULL, NULL, SND_CHN_MATRIX_3_1 },
- { "4.0", "4", "quad", SND_CHN_MATRIX_4_0 },
- { "4.1", NULL, NULL, SND_CHN_MATRIX_4_1 },
- { "5.0", "5", NULL, SND_CHN_MATRIX_5_0 },
- { "5.1", "6", NULL, SND_CHN_MATRIX_5_1 },
- { "6.0", NULL, NULL, SND_CHN_MATRIX_6_0 },
- { "6.1", "7", NULL, SND_CHN_MATRIX_6_1 },
- { "7.0", NULL, NULL, SND_CHN_MATRIX_7_0 },
- { "7.1", "8", NULL, SND_CHN_MATRIX_7_1 },
- { NULL, NULL, NULL, SND_CHN_MATRIX_UNKNOWN }
-};
-
uint32_t
snd_str2afmt(const char *req)
{
- uint32_t i, afmt;
- int matrix_id;
- char b1[8], b2[8];
+ int ext;
+ int ch;
+ int i;
+ char b1[8];
+ char b2[8];
+
+ memset(b1, 0, sizeof(b1));
+ memset(b2, 0, sizeof(b2));
i = sscanf(req, "%5[^:]:%6s", b1, b2);
@@ -1059,88 +1044,78 @@ snd_str2afmt(const char *req)
} else
return (0);
- afmt = 0;
- matrix_id = SND_CHN_MATRIX_UNKNOWN;
-
- for (i = 0; afmt == 0 && afmt_tab[i].name != NULL; i++) {
- if (strcasecmp(afmt_tab[i].name, b1) == 0 ||
- (afmt_tab[i].alias1 != NULL &&
- strcasecmp(afmt_tab[i].alias1, b1) == 0) ||
- (afmt_tab[i].alias2 != NULL &&
- strcasecmp(afmt_tab[i].alias2, b1) == 0)) {
- afmt = afmt_tab[i].afmt;
- strlcpy(b1, afmt_tab[i].name, sizeof(b1));
- }
- }
-
- if (afmt == 0)
+ i = sscanf(b2, "%d.%d", &ch, &ext);
+
+ if (i == 0) {
+ if (strcasecmp(b2, "mono") == 0) {
+ ch = 1;
+ ext = 0;
+ } else if (strcasecmp(b2, "stereo") == 0) {
+ ch = 2;
+ ext = 0;
+ } else if (strcasecmp(b2, "quad") == 0) {
+ ch = 4;
+ ext = 0;
+ } else
+ return (0);
+ } else if (i == 1) {
+ if (ch < 1 || ch > AFMT_CHANNEL_MAX)
+ return (0);
+ ext = 0;
+ } else if (i == 2) {
+ if (ext < 0 || ext > AFMT_EXTCHANNEL_MAX)
+ return (0);
+ if (ch < 1 || (ch + ext) > AFMT_CHANNEL_MAX)
+ return (0);
+ } else
return (0);
- for (i = 0; matrix_id == SND_CHN_MATRIX_UNKNOWN &&
- matrix_id_tab[i].name != NULL; i++) {
- if (strcmp(matrix_id_tab[i].name, b2) == 0 ||
- (matrix_id_tab[i].alias1 != NULL &&
- strcmp(matrix_id_tab[i].alias1, b2) == 0) ||
- (matrix_id_tab[i].alias2 != NULL &&
- strcasecmp(matrix_id_tab[i].alias2, b2) == 0)) {
- matrix_id = matrix_id_tab[i].matrix_id;
- strlcpy(b2, matrix_id_tab[i].name, sizeof(b2));
+ for (i = 0; afmt_tab[i].name != NULL; i++) {
+ if (strcasecmp(afmt_tab[i].name, b1) != 0) {
+ if (afmt_tab[i].alias1 == NULL)
+ continue;
+ if (strcasecmp(afmt_tab[i].alias1, b1) != 0) {
+ if (afmt_tab[i].alias2 == NULL)
+ continue;
+ if (strcasecmp(afmt_tab[i].alias2, b1) != 0)
+ continue;
+ }
}
+ /* found a match */
+ return (SND_FORMAT(afmt_tab[i].afmt, ch + ext, ext));
}
-
- if (matrix_id == SND_CHN_MATRIX_UNKNOWN)
- return (0);
-
-#ifndef _KERNEL
- printf("Parse OK: '%s' -> '%s:%s' %d\n", req, b1, b2,
- (int)(b2[0]) - '0' + (int)(b2[2]) - '0');
-#endif
-
- return (SND_FORMAT(afmt, b2[0] - '0' + b2[2] - '0', b2[2] - '0'));
+ /* not a valid format */
+ return (0);
}
uint32_t
snd_afmt2str(uint32_t afmt, char *buf, size_t len)
{
- uint32_t i, enc, ch, ext;
- char tmp[AFMTSTR_LEN];
+ uint32_t enc;
+ uint32_t ext;
+ uint32_t ch;
+ int i;
if (buf == NULL || len < AFMTSTR_LEN)
return (0);
-
- bzero(tmp, sizeof(tmp));
+ memset(buf, 0, len);
enc = AFMT_ENCODING(afmt);
ch = AFMT_CHANNEL(afmt);
ext = AFMT_EXTCHANNEL(afmt);
-
- for (i = 0; afmt_tab[i].name != NULL; i++) {
- if (enc == afmt_tab[i].afmt) {
- strlcpy(tmp, afmt_tab[i].name, sizeof(tmp));
- strlcat(tmp, ":", sizeof(tmp));
- break;
- }
- }
-
- if (strlen(tmp) == 0)
+ /* check there is at least one channel */
+ if (ch <= ext)
return (0);
-
- for (i = 0; matrix_id_tab[i].name != NULL; i++) {
- if (ch == (matrix_id_tab[i].name[0] - '0' +
- matrix_id_tab[i].name[2] - '0') &&
- ext == (matrix_id_tab[i].name[2] - '0')) {
- strlcat(tmp, matrix_id_tab[i].name, sizeof(tmp));
- break;
- }
+ for (i = 0; afmt_tab[i].name != NULL; i++) {
+ if (enc != afmt_tab[i].afmt)
+ continue;
+ /* found a match */
+ snprintf(buf, len, "%s:%d.%d",
+ afmt_tab[i].name, ch - ext, ext);
+ return (SND_FORMAT(enc, ch, ext));
}
-
- if (strlen(tmp) == 0)
- return (0);
-
- strlcpy(buf, tmp, len);
-
- return (snd_str2afmt(buf));
+ return (0);
}
int
diff --git a/sys/dev/sound/pcm/channel.h b/sys/dev/sound/pcm/channel.h
index 6601b54..45f43b5 100644
--- a/sys/dev/sound/pcm/channel.h
+++ b/sys/dev/sound/pcm/channel.h
@@ -162,6 +162,7 @@ struct pcm_channel {
} channels;
struct pcmchan_matrix matrix;
+ struct pcmchan_matrix matrix_scratch;
int volume[SND_VOL_C_MAX][SND_CHN_T_VOL_MAX];
diff --git a/sys/dev/sound/pcm/feeder_chain.c b/sys/dev/sound/pcm/feeder_chain.c
index a647269..308d5f2 100644
--- a/sys/dev/sound/pcm/feeder_chain.c
+++ b/sys/dev/sound/pcm/feeder_chain.c
@@ -561,6 +561,20 @@ feeder_build_mixer(struct pcm_channel *c, struct feeder_chain_desc *cdesc)
((c)->mode == FEEDER_CHAIN_LEAN && \
!((c)->current.afmt & (AFMT_S16_NE | AFMT_S32_NE)))))
+static void
+feeder_default_matrix(struct pcmchan_matrix *m, uint32_t fmt, int id)
+{
+ int x;
+
+ memset(m, 0, sizeof(*m));
+
+ m->id = id;
+ m->channels = AFMT_CHANNEL(fmt);
+ m->ext = AFMT_EXTCHANNEL(fmt);
+ for (x = 0; x != SND_CHN_T_MAX; x++)
+ m->offset[x] = -1;
+}
+
int
feeder_chain(struct pcm_channel *c)
{
@@ -641,10 +655,10 @@ feeder_chain(struct pcm_channel *c)
*/
hwmatrix = CHANNEL_GETMATRIX(c->methods, c->devinfo, hwfmt);
if (hwmatrix == NULL) {
- device_printf(c->dev,
- "%s(): failed to acquire hw matrix [0x%08x]\n",
- __func__, hwfmt);
- return (ENODEV);
+ /* setup a default matrix */
+ hwmatrix = &c->matrix_scratch;
+ feeder_default_matrix(hwmatrix, hwfmt,
+ SND_CHN_MATRIX_UNKNOWN);
}
/* ..... and rebuild hwfmt. */
hwfmt = SND_FORMAT(hwfmt, hwmatrix->channels, hwmatrix->ext);
@@ -656,13 +670,14 @@ feeder_chain(struct pcm_channel *c)
softmatrix->ext != AFMT_EXTCHANNEL(softfmt)) {
softmatrix = feeder_matrix_format_map(softfmt);
if (softmatrix == NULL) {
- device_printf(c->dev,
- "%s(): failed to acquire soft matrix [0x%08x]\n",
- __func__, softfmt);
- return (ENODEV);
+ /* setup a default matrix */
+ softmatrix = &c->matrix;
+ feeder_default_matrix(softmatrix, softfmt,
+ SND_CHN_MATRIX_PCMCHANNEL);
+ } else {
+ c->matrix = *softmatrix;
+ c->matrix.id = SND_CHN_MATRIX_PCMCHANNEL;
}
- c->matrix = *softmatrix;
- c->matrix.id = SND_CHN_MATRIX_PCMCHANNEL;
}
softfmt = SND_FORMAT(softfmt, softmatrix->channels, softmatrix->ext);
if (softfmt != c->format)
diff --git a/sys/dev/sound/pcm/sound.h b/sys/dev/sound/pcm/sound.h
index 3565ca5..32e0343 100644
--- a/sys/dev/sound/pcm/sound.h
+++ b/sys/dev/sound/pcm/sound.h
@@ -213,10 +213,12 @@ struct snd_mixer;
* ~(0xb00ff7ff)
*/
#define AFMT_ENCODING_MASK 0xf00fffff
-#define AFMT_CHANNEL_MASK 0x01f00000
+#define AFMT_CHANNEL_MASK 0x07f00000
#define AFMT_CHANNEL_SHIFT 20
-#define AFMT_EXTCHANNEL_MASK 0x0e000000
-#define AFMT_EXTCHANNEL_SHIFT 25
+#define AFMT_CHANNEL_MAX 0x7f
+#define AFMT_EXTCHANNEL_MASK 0x08000000
+#define AFMT_EXTCHANNEL_SHIFT 27
+#define AFMT_EXTCHANNEL_MAX 1
#define AFMT_ENCODING(v) ((v) & AFMT_ENCODING_MASK)
diff --git a/sys/dev/sound/usb/uaudio.c b/sys/dev/sound/usb/uaudio.c
index 8822bf0..063d8ce 100644
--- a/sys/dev/sound/usb/uaudio.c
+++ b/sys/dev/sound/usb/uaudio.c
@@ -115,6 +115,8 @@ SYSCTL_INT(_hw_usb_uaudio, OID_AUTO, default_channels, CTLFLAG_RWTUN,
#define UAUDIO_NFRAMES 64 /* must be factor of 8 due HS-USB */
#define UAUDIO_NCHANBUFS 2 /* number of outstanding request */
#define UAUDIO_RECURSE_LIMIT 255 /* rounds */
+#define UAUDIO_CHANNELS_MAX MIN(64, AFMT_CHANNEL_MAX)
+#define UAUDIO_MATRIX_MAX 8 /* channels */
#define MAKE_WORD(h,l) (((h) << 8) | (l))
#define BIT_TEST(bm,bno) (((bm)[(bno) / 8] >> (7 - ((bno) % 8))) & 1)
@@ -346,6 +348,7 @@ struct uaudio_softc {
uint8_t sc_uq_au_no_xu:1;
uint8_t sc_uq_bad_adc:1;
uint8_t sc_uq_au_vendor_class:1;
+ uint8_t sc_pcm_bitperfect:1;
};
struct uaudio_terminal_node {
@@ -1062,6 +1065,10 @@ uaudio_attach_sub(device_t dev, kobj_class_t mixer_class, kobj_class_t chan_clas
*/
uaudio_pcm_setflags(dev, SD_F_SOFTPCMVOL);
}
+ if (sc->sc_pcm_bitperfect) {
+ DPRINTF("device needs bitperfect by default\n");
+ uaudio_pcm_setflags(dev, SD_F_BITPERFECT);
+ }
if (mixer_init(dev, mixer_class, sc))
goto detach;
sc->sc_mixer_init = 1;
@@ -1568,6 +1575,19 @@ uaudio_chan_fill_info_sub(struct uaudio_softc *sc, struct usb_device *udev,
asf1d.v1 = NULL;
ed1 = NULL;
sed.v1 = NULL;
+
+ /*
+ * There can only be one USB audio instance
+ * per USB device. Grab all USB audio
+ * interfaces on this USB device so that we
+ * don't attach USB audio twice:
+ */
+ if (alt_index == 0 && curidx != sc->sc_mixer_iface_index &&
+ (id->bInterfaceClass == UICLASS_AUDIO || audio_if != 0 ||
+ midi_if != 0)) {
+ usbd_set_parent_iface(sc->sc_udev, curidx,
+ sc->sc_mixer_iface_index);
+ }
}
if (audio_if == 0) {
@@ -1803,9 +1823,6 @@ uaudio_chan_fill_info_sub(struct uaudio_softc *sc, struct usb_device *udev,
chan_alt->iface_index = curidx;
chan_alt->iface_alt_index = alt_index;
- usbd_set_parent_iface(sc->sc_udev, curidx,
- sc->sc_mixer_iface_index);
-
if (ep_dir == UE_DIR_IN)
chan_alt->usb_cfg = uaudio_cfg_record;
else
@@ -1826,19 +1843,21 @@ uaudio_chan_fill_info_sub(struct uaudio_softc *sc, struct usb_device *udev,
format = chan_alt->p_fmt->freebsd_fmt;
+ /* get default SND_FORMAT() */
+ format = SND_FORMAT(format, chan_alt->channels, 0);
+
switch (chan_alt->channels) {
- case 2:
- /* stereo */
- format = SND_FORMAT(format, 2, 0);
- break;
+ uint32_t temp_fmt;
case 1:
- /* mono */
- format = SND_FORMAT(format, 1, 0);
+ case 2:
+ /* mono and stereo */
break;
default:
/* surround and more */
- format = feeder_matrix_default_format(
- SND_FORMAT(format, chan_alt->channels, 0));
+ temp_fmt = feeder_matrix_default_format(format);
+ /* if multichannel, then format can be zero */
+ if (temp_fmt != 0)
+ format = temp_fmt;
break;
}
@@ -1865,6 +1884,10 @@ uaudio_chan_fill_info_sub(struct uaudio_softc *sc, struct usb_device *udev,
chan->pcm_cap.fmtlist = chan->pcm_format;
chan->pcm_cap.fmtlist[0] = format;
+ /* check if device needs bitperfect */
+ if (chan_alt->channels > UAUDIO_MATRIX_MAX)
+ sc->sc_pcm_bitperfect = 1;
+
if (rate < chan->pcm_cap.minspeed || chan->pcm_cap.minspeed == 0)
chan->pcm_cap.minspeed = rate;
if (rate > chan->pcm_cap.maxspeed || chan->pcm_cap.maxspeed == 0)
@@ -1939,15 +1962,15 @@ uaudio_chan_fill_info(struct uaudio_softc *sc, struct usb_device *udev)
channels = 4;
break;
default:
- channels = 16;
+ channels = UAUDIO_CHANNELS_MAX;
break;
}
- } else if (channels > 16) {
- channels = 16;
- }
- if (sbuf_new(&sc->sc_sndstat, NULL, 4096, SBUF_AUTOEXTEND)) {
+ } else if (channels > UAUDIO_CHANNELS_MAX)
+ channels = UAUDIO_CHANNELS_MAX;
+
+ if (sbuf_new(&sc->sc_sndstat, NULL, 4096, SBUF_AUTOEXTEND))
sc->sc_sndstat_valid = 1;
- }
+
/* try to search for a valid config */
for (x = channels; x; x--) {
diff --git a/sys/dev/usb/quirk/usb_quirk.c b/sys/dev/usb/quirk/usb_quirk.c
index e0c5db7..3cfaef0 100644
--- a/sys/dev/usb/quirk/usb_quirk.c
+++ b/sys/dev/usb/quirk/usb_quirk.c
@@ -523,6 +523,9 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
USB_QUIRK(FEIYA, DUMMY, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE, UQ_MATCH_VENDOR_ONLY),
USB_QUIRK(REALTEK, DUMMY, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE, UQ_MATCH_VENDOR_ONLY),
USB_QUIRK(INITIO, DUMMY, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE, UQ_MATCH_VENDOR_ONLY),
+
+ /* DYMO LabelManager Pnp */
+ USB_QUIRK(DYMO, LABELMANAGERPNP, 0x0000, 0xffff, UQ_MSC_DYMO_EJECT),
};
#undef USB_QUIRK_VP
#undef USB_QUIRK
@@ -592,6 +595,7 @@ static const char *usb_quirk_str[USB_QUIRK_MAX] = {
[UQ_BAD_MIDI] = "UQ_BAD_MIDI",
[UQ_AU_VENDOR_CLASS] = "UQ_AU_VENDOR_CLASS",
[UQ_SINGLE_CMD_MIDI] = "UQ_SINGLE_CMD_MIDI",
+ [UQ_MSC_DYMO_EJECT] = "UQ_MSC_DYMO_EJECT",
};
/*------------------------------------------------------------------------*
diff --git a/sys/dev/usb/quirk/usb_quirk.h b/sys/dev/usb/quirk/usb_quirk.h
index c2e9501..7010916 100644
--- a/sys/dev/usb/quirk/usb_quirk.h
+++ b/sys/dev/usb/quirk/usb_quirk.h
@@ -108,6 +108,7 @@ enum {
UQ_BAD_MIDI, /* device claims MIDI class, but isn't */
UQ_AU_VENDOR_CLASS, /* audio device uses vendor and not audio class */
UQ_SINGLE_CMD_MIDI, /* at most one command per USB packet */
+ UQ_MSC_DYMO_EJECT, /* ejects Dymo MSC device */
USB_QUIRK_MAX
};
diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c
index b3b46b3..5ffc07f 100644
--- a/sys/dev/usb/usb_device.c
+++ b/sys/dev/usb/usb_device.c
@@ -1343,6 +1343,12 @@ usb_probe_and_attach(struct usb_device *udev, uint8_t iface_index)
*/
if (iface_index == USB_IFACE_INDEX_ANY) {
+ if (usb_test_quirk(&uaa, UQ_MSC_DYMO_EJECT) != 0 &&
+ usb_dymo_eject(udev, 0) == 0) {
+ /* success, mark the udev as disappearing */
+ uaa.dev_state = UAA_DEV_EJECTING;
+ }
+
EVENTHANDLER_INVOKE(usb_dev_configured, udev, &uaa);
if (uaa.dev_state != UAA_DEV_READY) {
diff --git a/sys/dev/usb/usb_msctest.c b/sys/dev/usb/usb_msctest.c
index c77afd0..b99fd29 100644
--- a/sys/dev/usb/usb_msctest.c
+++ b/sys/dev/usb/usb_msctest.c
@@ -181,6 +181,7 @@ static usb_callback_t bbb_data_rd_cs_callback;
static usb_callback_t bbb_data_write_callback;
static usb_callback_t bbb_data_wr_cs_callback;
static usb_callback_t bbb_status_callback;
+static usb_callback_t bbb_raw_write_callback;
static void bbb_done(struct bbb_transfer *, int);
static void bbb_transfer_start(struct bbb_transfer *, uint8_t);
@@ -188,7 +189,7 @@ static void bbb_data_clear_stall_callback(struct usb_xfer *, uint8_t,
uint8_t);
static int bbb_command_start(struct bbb_transfer *, uint8_t, uint8_t,
void *, size_t, void *, size_t, usb_timeout_t);
-static struct bbb_transfer *bbb_attach(struct usb_device *, uint8_t);
+static struct bbb_transfer *bbb_attach(struct usb_device *, uint8_t, uint8_t);
static void bbb_detach(struct bbb_transfer *);
static const struct usb_config bbb_config[ST_MAX] = {
@@ -251,6 +252,19 @@ static const struct usb_config bbb_config[ST_MAX] = {
},
};
+static const struct usb_config bbb_raw_config[1] = {
+
+ [0] = {
+ .type = UE_BULK_INTR,
+ .endpoint = UE_ADDR_ANY,
+ .direction = UE_DIR_OUT,
+ .bufsize = SCSI_MAX_LEN,
+ .flags = {.ext_buffer = 1,.proxy_buffer = 1,},
+ .callback = &bbb_raw_write_callback,
+ .timeout = 1 * USB_MS_HZ, /* 1 second */
+ },
+};
+
static void
bbb_done(struct bbb_transfer *sc, int error)
{
@@ -471,6 +485,47 @@ bbb_status_callback(struct usb_xfer *xfer, usb_error_t error)
}
}
+static void
+bbb_raw_write_callback(struct usb_xfer *xfer, usb_error_t error)
+{
+ struct bbb_transfer *sc = usbd_xfer_softc(xfer);
+ usb_frlength_t max_bulk = usbd_xfer_max_len(xfer);
+ int actlen, sumlen;
+
+ usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL);
+
+ switch (USB_GET_STATE(xfer)) {
+ case USB_ST_TRANSFERRED:
+ sc->data_rem -= actlen;
+ sc->data_ptr += actlen;
+ sc->actlen += actlen;
+
+ if (actlen < sumlen) {
+ /* short transfer */
+ sc->data_rem = 0;
+ }
+ case USB_ST_SETUP:
+ DPRINTF("max_bulk=%d, data_rem=%d\n",
+ max_bulk, sc->data_rem);
+
+ if (sc->data_rem == 0) {
+ bbb_done(sc, 0);
+ break;
+ }
+ if (max_bulk > sc->data_rem) {
+ max_bulk = sc->data_rem;
+ }
+ usbd_xfer_set_timeout(xfer, sc->data_timeout);
+ usbd_xfer_set_frame_data(xfer, 0, sc->data_ptr, max_bulk);
+ usbd_transfer_submit(xfer);
+ break;
+
+ default: /* Error */
+ bbb_done(sc, error);
+ break;
+ }
+}
+
/*------------------------------------------------------------------------*
* bbb_command_start - execute a SCSI command synchronously
*
@@ -506,13 +561,45 @@ bbb_command_start(struct bbb_transfer *sc, uint8_t dir, uint8_t lun,
return (sc->error);
}
+/*------------------------------------------------------------------------*
+ * bbb_raw_write - write a raw BULK message synchronously
+ *
+ * Return values
+ * 0: Success
+ * Else: Failure
+ *------------------------------------------------------------------------*/
+static int
+bbb_raw_write(struct bbb_transfer *sc, const void *data_ptr, size_t data_len,
+ usb_timeout_t data_timeout)
+{
+ sc->data_ptr = __DECONST(void *, data_ptr);
+ sc->data_len = data_len;
+ sc->data_rem = data_len;
+ sc->data_timeout = (data_timeout + USB_MS_HZ);
+ sc->actlen = 0;
+ sc->error = 0;
+
+ DPRINTFN(1, "BULK DATA = %*D\n", (int)data_len,
+ (const char *)data_ptr, ":");
+
+ mtx_lock(&sc->mtx);
+ usbd_transfer_start(sc->xfer[0]);
+ while (usbd_transfer_pending(sc->xfer[0]))
+ cv_wait(&sc->cv, &sc->mtx);
+ mtx_unlock(&sc->mtx);
+ return (sc->error);
+}
+
static struct bbb_transfer *
-bbb_attach(struct usb_device *udev, uint8_t iface_index)
+bbb_attach(struct usb_device *udev, uint8_t iface_index,
+ uint8_t bInterfaceClass)
{
struct usb_interface *iface;
struct usb_interface_descriptor *id;
+ const struct usb_config *pconfig;
struct bbb_transfer *sc;
usb_error_t err;
+ int nconfig;
#if USB_HAVE_MSCTEST_DETACH
uint8_t do_unlock;
@@ -535,22 +622,39 @@ bbb_attach(struct usb_device *udev, uint8_t iface_index)
return (NULL);
id = iface->idesc;
- if (id == NULL || id->bInterfaceClass != UICLASS_MASS)
+ if (id == NULL || id->bInterfaceClass != bInterfaceClass)
return (NULL);
- switch (id->bInterfaceSubClass) {
- case UISUBCLASS_SCSI:
- case UISUBCLASS_UFI:
- case UISUBCLASS_SFF8020I:
- case UISUBCLASS_SFF8070I:
+ switch (id->bInterfaceClass) {
+ case UICLASS_MASS:
+ switch (id->bInterfaceSubClass) {
+ case UISUBCLASS_SCSI:
+ case UISUBCLASS_UFI:
+ case UISUBCLASS_SFF8020I:
+ case UISUBCLASS_SFF8070I:
+ break;
+ default:
+ return (NULL);
+ }
+ switch (id->bInterfaceProtocol) {
+ case UIPROTO_MASS_BBB_OLD:
+ case UIPROTO_MASS_BBB:
+ break;
+ default:
+ return (NULL);
+ }
+ pconfig = bbb_config;
+ nconfig = ST_MAX;
break;
- default:
- return (NULL);
- }
-
- switch (id->bInterfaceProtocol) {
- case UIPROTO_MASS_BBB_OLD:
- case UIPROTO_MASS_BBB:
+ case UICLASS_HID:
+ switch (id->bInterfaceSubClass) {
+ case 0:
+ break;
+ default:
+ return (NULL);
+ }
+ pconfig = bbb_raw_config;
+ nconfig = 1;
break;
default:
return (NULL);
@@ -560,22 +664,27 @@ bbb_attach(struct usb_device *udev, uint8_t iface_index)
mtx_init(&sc->mtx, "USB autoinstall", NULL, MTX_DEF);
cv_init(&sc->cv, "WBBB");
- err = usbd_transfer_setup(udev, &iface_index, sc->xfer, bbb_config,
- ST_MAX, sc, &sc->mtx);
+ err = usbd_transfer_setup(udev, &iface_index, sc->xfer, pconfig,
+ nconfig, sc, &sc->mtx);
if (err) {
bbb_detach(sc);
return (NULL);
}
- /* store pointer to DMA buffers */
- sc->buffer = usbd_xfer_get_frame_buffer(
- sc->xfer[ST_DATA_RD], 0);
- sc->buffer_size =
- usbd_xfer_max_len(sc->xfer[ST_DATA_RD]);
- sc->cbw = usbd_xfer_get_frame_buffer(
- sc->xfer[ST_COMMAND], 0);
- sc->csw = usbd_xfer_get_frame_buffer(
- sc->xfer[ST_STATUS], 0);
-
+ switch (id->bInterfaceClass) {
+ case UICLASS_MASS:
+ /* store pointer to DMA buffers */
+ sc->buffer = usbd_xfer_get_frame_buffer(
+ sc->xfer[ST_DATA_RD], 0);
+ sc->buffer_size =
+ usbd_xfer_max_len(sc->xfer[ST_DATA_RD]);
+ sc->cbw = usbd_xfer_get_frame_buffer(
+ sc->xfer[ST_COMMAND], 0);
+ sc->csw = usbd_xfer_get_frame_buffer(
+ sc->xfer[ST_STATUS], 0);
+ break;
+ default:
+ break;
+ }
return (sc);
}
@@ -604,7 +713,7 @@ usb_iface_is_cdrom(struct usb_device *udev, uint8_t iface_index)
uint8_t sid_type;
int err;
- sc = bbb_attach(udev, iface_index);
+ sc = bbb_attach(udev, iface_index, UICLASS_MASS);
if (sc == NULL)
return (0);
@@ -660,7 +769,7 @@ usb_msc_auto_quirk(struct usb_device *udev, uint8_t iface_index)
uint8_t sid_type;
int err;
- sc = bbb_attach(udev, iface_index);
+ sc = bbb_attach(udev, iface_index, UICLASS_MASS);
if (sc == NULL)
return (0);
@@ -829,7 +938,7 @@ usb_msc_eject(struct usb_device *udev, uint8_t iface_index, int method)
struct bbb_transfer *sc;
usb_error_t err;
- sc = bbb_attach(udev, iface_index);
+ sc = bbb_attach(udev, iface_index, UICLASS_MASS);
if (sc == NULL)
return (USB_ERR_INVAL);
@@ -890,6 +999,21 @@ usb_msc_eject(struct usb_device *udev, uint8_t iface_index, int method)
}
usb_error_t
+usb_dymo_eject(struct usb_device *udev, uint8_t iface_index)
+{
+ static const uint8_t data[3] = { 0x1b, 0x5a, 0x01 };
+ struct bbb_transfer *sc;
+ usb_error_t err;
+
+ sc = bbb_attach(udev, iface_index, UICLASS_HID);
+ if (sc == NULL)
+ return (USB_ERR_INVAL);
+ err = bbb_raw_write(sc, data, sizeof(data), USB_MS_HZ);
+ bbb_detach(sc);
+ return (err);
+}
+
+usb_error_t
usb_msc_read_10(struct usb_device *udev, uint8_t iface_index,
uint32_t lba, uint32_t blocks, void *buffer)
{
@@ -908,7 +1032,7 @@ usb_msc_read_10(struct usb_device *udev, uint8_t iface_index,
cmd[8] = blocks;
cmd[9] = 0;
- sc = bbb_attach(udev, iface_index);
+ sc = bbb_attach(udev, iface_index, UICLASS_MASS);
if (sc == NULL)
return (USB_ERR_INVAL);
@@ -939,7 +1063,7 @@ usb_msc_write_10(struct usb_device *udev, uint8_t iface_index,
cmd[8] = blocks;
cmd[9] = 0;
- sc = bbb_attach(udev, iface_index);
+ sc = bbb_attach(udev, iface_index, UICLASS_MASS);
if (sc == NULL)
return (USB_ERR_INVAL);
@@ -958,7 +1082,7 @@ usb_msc_read_capacity(struct usb_device *udev, uint8_t iface_index,
struct bbb_transfer *sc;
usb_error_t err;
- sc = bbb_attach(udev, iface_index);
+ sc = bbb_attach(udev, iface_index, UICLASS_MASS);
if (sc == NULL)
return (USB_ERR_INVAL);
diff --git a/sys/dev/usb/usb_msctest.h b/sys/dev/usb/usb_msctest.h
index dcc3cf7..d3f26c2 100644
--- a/sys/dev/usb/usb_msctest.h
+++ b/sys/dev/usb/usb_msctest.h
@@ -52,5 +52,7 @@ usb_error_t usb_msc_write_10(struct usb_device *udev,
usb_error_t usb_msc_read_capacity(struct usb_device *udev,
uint8_t iface_index, uint32_t *lba_last,
uint32_t *block_size);
+usb_error_t usb_dymo_eject(struct usb_device *udev,
+ uint8_t iface_index);
#endif /* _USB_MSCTEST_H_ */
diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
index abe2e6f..f8ba5b5 100644
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -452,6 +452,7 @@ vendor GLOBESPAN 0x0915 Globespan
vendor CONCORDCAMERA 0x0919 Concord Camera
vendor GARMIN 0x091e Garmin International
vendor GOHUBS 0x0921 GoHubs
+vendor DYMO 0x0922 DYMO
vendor XEROX 0x0924 Xerox
vendor BIOMETRIC 0x0929 American Biometric Company
vendor TOSHIBA 0x0930 Toshiba
@@ -1694,6 +1695,9 @@ product DRESDENELEKTRONIK WIRELESSHANDHELDTERMINAL 0x0004 Wireless Handheld Ter
product DRESDENELEKTRONIK DE_RFNODE 0x001c deRFnode
product DRESDENELEKTRONIK LEVELSHIFTERSTICKLOWCOST 0x0022 Levelshifter Stick Low Cost
+/* DYMO */
+product DYMO LABELMANAGERPNP 0x1001 DYMO LabelManager PnP
+
/* Dynastream Innovations */
product DYNASTREAM ANTDEVBOARD 0x1003 ANT dev board
product DYNASTREAM ANT2USB 0x1004 ANT2USB
diff --git a/sys/dev/usb/wlan/if_urtwn.c b/sys/dev/usb/wlan/if_urtwn.c
index 72004d9..331f782 100644
--- a/sys/dev/usb/wlan/if_urtwn.c
+++ b/sys/dev/usb/wlan/if_urtwn.c
@@ -1195,7 +1195,7 @@ urtwn_efuse_read(struct urtwn_softc *sc)
uint8_t *rom = (uint8_t *)&sc->rom;
uint16_t addr = 0;
uint32_t reg;
- uint8_t off, msk, vol;
+ uint8_t off, msk;
int i;
urtwn_efuse_switch_power(sc);
@@ -1228,18 +1228,15 @@ urtwn_efuse_read(struct urtwn_softc *sc)
printf("\n");
}
#endif
- /* Disable LDO 2.5V. */
- vol = urtwn_read_1(sc, R92C_EFUSE_TEST + 3);
- urtwn_write_1(sc, R92C_EFUSE_TEST + 3, vol & ~(0x80));
-
+ urtwn_write_1(sc, R92C_EFUSE_ACCESS, R92C_EFUSE_ACCESS_OFF);
}
+
static void
urtwn_efuse_switch_power(struct urtwn_softc *sc)
{
uint32_t reg;
- if (sc->chip & URTWN_CHIP_88E)
- urtwn_write_1(sc, R92C_EFUSE_ACCESS, R92C_EFUSE_ACCESS_ON);
+ urtwn_write_1(sc, R92C_EFUSE_ACCESS, R92C_EFUSE_ACCESS_ON);
reg = urtwn_read_2(sc, R92C_SYS_ISO_CTRL);
if (!(reg & R92C_SYS_ISO_CTRL_PWC_EV12V)) {
@@ -1257,16 +1254,6 @@ urtwn_efuse_switch_power(struct urtwn_softc *sc)
urtwn_write_2(sc, R92C_SYS_CLKR,
reg | R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M);
}
-
- if (!(sc->chip & URTWN_CHIP_88E)) {
- uint8_t vol;
-
- /* Enable LDO 2.5V. */
- vol = urtwn_read_1(sc, R92C_EFUSE_TEST + 3);
- vol &= 0x0f;
- vol |= 0x30;
- urtwn_write_1(sc, R92C_EFUSE_TEST + 3, (vol | 0x80));
- }
}
static int
@@ -1905,10 +1892,7 @@ urtwn_tx_start(struct urtwn_softc *sc, struct ieee80211_node *ni,
txd->txdw4 |= htole32(SM(R92C_TXDW4_RTSRATE, 8));
txd->txdw5 |= htole32(0x0001ff00);
/* Send data at OFDM54. */
- if (sc->chip & URTWN_CHIP_88E)
- txd->txdw5 |= htole32(0x13 & 0x3f);
- else
- txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 11));
+ txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 11));
} else {
txd->txdw1 |= htole32(
SM(R92C_TXDW1_MACID, 0) |
@@ -3364,6 +3348,7 @@ urtwn_init_locked(void *arg)
urtwn_rxfilter_init(sc);
+ /* Set response rate. */
reg = urtwn_read_4(sc, R92C_RRSR);
reg = RW(reg, R92C_RRSR_RATE_BITMAP, R92C_RRSR_RATE_CCK_ONLY_1M);
urtwn_write_4(sc, R92C_RRSR, reg);
diff --git a/sys/dev/usb/wlan/if_urtwnreg.h b/sys/dev/usb/wlan/if_urtwnreg.h
index 4eef029..2bbec7a 100644
--- a/sys/dev/usb/wlan/if_urtwnreg.h
+++ b/sys/dev/usb/wlan/if_urtwnreg.h
@@ -177,13 +177,13 @@
#define R92C_RD_NAV_NXT 0x544
#define R92C_NAV_PROT_LEN 0x546
#define R92C_BCN_CTRL 0x550
-#define R92C_USTIME_TSF 0x551
#define R92C_MBID_NUM 0x552
#define R92C_DUAL_TSF_RST 0x553
#define R92C_BCN_INTERVAL 0x554
#define R92C_DRVERLYINT 0x558
#define R92C_BCNDMATIM 0x559
#define R92C_ATIMWND 0x55a
+#define R92C_USTIME_TSF 0x55c
#define R92C_BCN_MAX_ERR 0x55d
#define R92C_RXTSF_OFFSET_CCK 0x55e
#define R92C_RXTSF_OFFSET_OFDM 0x55f
diff --git a/sys/dev/vt/vt.h b/sys/dev/vt/vt.h
index 85c0345..bdfcf46 100644
--- a/sys/dev/vt/vt.h
+++ b/sys/dev/vt/vt.h
@@ -83,9 +83,8 @@
#define ISSIGVALID(sig) ((sig) > 0 && (sig) < NSIG)
#define VT_SYSCTL_INT(_name, _default, _descr) \
-static int vt_##_name = _default; \
-SYSCTL_INT(_kern_vt, OID_AUTO, _name, CTLFLAG_RWTUN, &vt_##_name, _default,\
- _descr);
+static int vt_##_name = (_default); \
+SYSCTL_INT(_kern_vt, OID_AUTO, _name, CTLFLAG_RWTUN, &vt_##_name, 0, _descr)
struct vt_driver;
diff --git a/sys/dev/vt/vt_core.c b/sys/dev/vt/vt_core.c
index a637055..e6603a9 100644
--- a/sys/dev/vt/vt_core.c
+++ b/sys/dev/vt/vt_core.c
@@ -451,12 +451,35 @@ vt_proc_window_switch(struct vt_window *vw)
struct vt_device *vd;
int ret;
+ /* Prevent switching to NULL */
+ if (vw == NULL) {
+ DPRINTF(30, "%s: Cannot switch: vw is NULL.", __func__);
+ return (EINVAL);
+ }
vd = vw->vw_device;
curvw = vd->vd_curwindow;
+ /* Check if virtual terminal is locked */
if (curvw->vw_flags & VWF_VTYLOCK)
return (EBUSY);
+ /* Check if switch already in progress */
+ if (curvw->vw_flags & VWF_SWWAIT_REL) {
+ /* Check if switching to same window */
+ if (curvw->vw_switch_to == vw) {
+ DPRINTF(30, "%s: Switch in progress to same vw.", __func__);
+ return (0); /* success */
+ }
+ DPRINTF(30, "%s: Switch in progress to different vw.", __func__);
+ return (EBUSY);
+ }
+
+ /* Avoid switching to already selected window */
+ if (vw == curvw) {
+ DPRINTF(30, "%s: Cannot switch: vw == curvw.", __func__);
+ return (0); /* success */
+ }
+
/* Ask current process permission to switch away. */
if (curvw->vw_smode.mode == VT_PROCESS) {
DPRINTF(30, "%s: VT_PROCESS ", __func__);
@@ -664,8 +687,7 @@ vt_scrollmode_kbdevent(struct vt_window *vw, int c, int console)
if (console == 0) {
if (c >= F_SCR && c <= MIN(L_SCR, F_SCR + VT_MAXWINDOWS - 1)) {
vw = vd->vd_windows[c - F_SCR];
- if (vw != NULL)
- vt_proc_window_switch(vw);
+ vt_proc_window_switch(vw);
return;
}
VT_LOCK(vd);
@@ -750,8 +772,7 @@ vt_processkey(keyboard_t *kbd, struct vt_device *vd, int c)
if (c >= F_SCR && c <= MIN(L_SCR, F_SCR + VT_MAXWINDOWS - 1)) {
vw = vd->vd_windows[c - F_SCR];
- if (vw != NULL)
- vt_proc_window_switch(vw);
+ vt_proc_window_switch(vw);
return (0);
}
@@ -760,15 +781,13 @@ vt_processkey(keyboard_t *kbd, struct vt_device *vd, int c)
/* Switch to next VT. */
c = (vw->vw_number + 1) % VT_MAXWINDOWS;
vw = vd->vd_windows[c];
- if (vw != NULL)
- vt_proc_window_switch(vw);
+ vt_proc_window_switch(vw);
return (0);
case PREV:
/* Switch to previous VT. */
c = (vw->vw_number - 1) % VT_MAXWINDOWS;
vw = vd->vd_windows[c];
- if (vw != NULL)
- vt_proc_window_switch(vw);
+ vt_proc_window_switch(vw);
return (0);
case SLK: {
vt_save_kbd_state(vw, kbd);
@@ -2774,8 +2793,7 @@ vt_resume(struct vt_device *vd)
if (vt_suspendswitch == 0)
return;
- /* Switch back to saved window */
- if (vd->vd_savedwindow != NULL)
- vt_proc_window_switch(vd->vd_savedwindow);
+ /* Switch back to saved window, if any */
+ vt_proc_window_switch(vd->vd_savedwindow);
vd->vd_savedwindow = NULL;
}
diff --git a/sys/dev/xen/blkback/blkback.c b/sys/dev/xen/blkback/blkback.c
index b647fec..d352242 100644
--- a/sys/dev/xen/blkback/blkback.c
+++ b/sys/dev/xen/blkback/blkback.c
@@ -2817,9 +2817,8 @@ xbb_free_communication_mem(struct xbb_softc *xbb)
{
if (xbb->kva != 0) {
if (xbb->pseudo_phys_res != NULL) {
- bus_release_resource(xbb->dev, SYS_RES_MEMORY,
- xbb->pseudo_phys_res_id,
- xbb->pseudo_phys_res);
+ xenmem_free(xbb->dev, xbb->pseudo_phys_res_id,
+ xbb->pseudo_phys_res);
xbb->pseudo_phys_res = NULL;
}
}
@@ -3056,10 +3055,8 @@ xbb_alloc_communication_mem(struct xbb_softc *xbb)
* via grant table operations.
*/
xbb->pseudo_phys_res_id = 0;
- xbb->pseudo_phys_res = bus_alloc_resource(xbb->dev, SYS_RES_MEMORY,
- &xbb->pseudo_phys_res_id,
- 0, ~0, xbb->kva_size,
- RF_ACTIVE);
+ xbb->pseudo_phys_res = xenmem_alloc(xbb->dev, &xbb->pseudo_phys_res_id,
+ xbb->kva_size);
if (xbb->pseudo_phys_res == NULL) {
xbb->kva = 0;
return (ENOMEM);
diff --git a/sys/dev/xen/grant_table/grant_table.c b/sys/dev/xen/grant_table/grant_table.c
index ad65fe0..728d64d 100644
--- a/sys/dev/xen/grant_table/grant_table.c
+++ b/sys/dev/xen/grant_table/grant_table.c
@@ -559,9 +559,8 @@ gnttab_resume(device_t dev)
KASSERT(dev != NULL,
("No resume frames and no device provided"));
- gnttab_pseudo_phys_res = bus_alloc_resource(dev,
- SYS_RES_MEMORY, &gnttab_pseudo_phys_res_id, 0, ~0,
- PAGE_SIZE * max_nr_gframes, RF_ACTIVE);
+ gnttab_pseudo_phys_res = xenmem_alloc(dev,
+ &gnttab_pseudo_phys_res_id, PAGE_SIZE * max_nr_gframes);
if (gnttab_pseudo_phys_res == NULL)
panic("Unable to reserve physical memory for gnttab");
resume_frames = rman_get_start(gnttab_pseudo_phys_res);
diff --git a/sys/dev/xen/netback/netback.c b/sys/dev/xen/netback/netback.c
index b5c1c13..2233084 100644
--- a/sys/dev/xen/netback/netback.c
+++ b/sys/dev/xen/netback/netback.c
@@ -625,8 +625,7 @@ xnb_free_communication_mem(struct xnb_softc *xnb)
{
if (xnb->kva != 0) {
if (xnb->pseudo_phys_res != NULL) {
- bus_release_resource(xnb->dev, SYS_RES_MEMORY,
- xnb->pseudo_phys_res_id,
+ xenmem_free(xnb->dev, xnb->pseudo_phys_res_id,
xnb->pseudo_phys_res);
xnb->pseudo_phys_res = NULL;
}
@@ -819,10 +818,8 @@ xnb_alloc_communication_mem(struct xnb_softc *xnb)
* into this space.
*/
xnb->pseudo_phys_res_id = 0;
- xnb->pseudo_phys_res = bus_alloc_resource(xnb->dev, SYS_RES_MEMORY,
- &xnb->pseudo_phys_res_id,
- 0, ~0, xnb->kva_size,
- RF_ACTIVE);
+ xnb->pseudo_phys_res = xenmem_alloc(xnb->dev, &xnb->pseudo_phys_res_id,
+ xnb->kva_size);
if (xnb->pseudo_phys_res == NULL) {
xnb->kva = 0;
return (ENOMEM);
diff --git a/sys/dev/xen/privcmd/privcmd.c b/sys/dev/xen/privcmd/privcmd.c
index 761fb03..0bf9585 100644
--- a/sys/dev/xen/privcmd/privcmd.c
+++ b/sys/dev/xen/privcmd/privcmd.c
@@ -141,11 +141,8 @@ retry:
free(map->errs, M_PRIVCMD);
}
- vm_phys_fictitious_unreg_range(map->phys_base_addr,
- map->phys_base_addr + map->size * PAGE_SIZE);
-
- error = bus_release_resource(privcmd_dev, SYS_RES_MEMORY,
- map->pseudo_phys_res_id, map->pseudo_phys_res);
+ error = xenmem_free(privcmd_dev, map->pseudo_phys_res_id,
+ map->pseudo_phys_res);
KASSERT(error == 0, ("Unable to release memory resource: %d", error));
free(map, M_PRIVCMD);
@@ -196,36 +193,25 @@ privcmd_mmap_single(struct cdev *cdev, vm_ooffset_t *offset, vm_size_t size,
vm_object_t *object, int nprot)
{
struct privcmd_map *map;
- int error;
map = malloc(sizeof(*map), M_PRIVCMD, M_WAITOK | M_ZERO);
map->size = OFF_TO_IDX(size);
map->pseudo_phys_res_id = 0;
- map->pseudo_phys_res = bus_alloc_resource(privcmd_dev, SYS_RES_MEMORY,
- &map->pseudo_phys_res_id, 0, ~0, size, RF_ACTIVE);
+ map->pseudo_phys_res = xenmem_alloc(privcmd_dev,
+ &map->pseudo_phys_res_id, size);
if (map->pseudo_phys_res == NULL) {
free(map, M_PRIVCMD);
return (ENOMEM);
}
map->phys_base_addr = rman_get_start(map->pseudo_phys_res);
-
- error = vm_phys_fictitious_reg_range(map->phys_base_addr,
- map->phys_base_addr + size, VM_MEMATTR_DEFAULT);
- if (error) {
- bus_release_resource(privcmd_dev, SYS_RES_MEMORY,
- map->pseudo_phys_res_id, map->pseudo_phys_res);
- free(map, M_PRIVCMD);
- return (error);
- }
-
map->mem = cdev_pager_allocate(map, OBJT_MGTDEVICE, &privcmd_pg_ops,
size, nprot, *offset, NULL);
if (map->mem == NULL) {
- bus_release_resource(privcmd_dev, SYS_RES_MEMORY,
- map->pseudo_phys_res_id, map->pseudo_phys_res);
+ xenmem_free(privcmd_dev, map->pseudo_phys_res_id,
+ map->pseudo_phys_res);
free(map, M_PRIVCMD);
return (ENOMEM);
}
diff --git a/sys/i386/acpica/acpi_machdep.c b/sys/i386/acpica/acpi_machdep.c
index 049354b..4c79691 100644
--- a/sys/i386/acpica/acpi_machdep.c
+++ b/sys/i386/acpica/acpi_machdep.c
@@ -106,13 +106,6 @@ acpi_machdep_quirks(int *quirks)
return (0);
}
-void
-acpi_cpu_c1()
-{
-
- __asm __volatile("sti; hlt");
-}
-
/*
* Support for mapping ACPI tables during early boot. This abuses the
* crashdump map because the kernel cannot allocate KVA in
diff --git a/sys/i386/include/md_var.h b/sys/i386/include/md_var.h
index bffdd57..b5bd35e 100644
--- a/sys/i386/include/md_var.h
+++ b/sys/i386/include/md_var.h
@@ -97,6 +97,7 @@ struct dumperinfo;
void *alloc_fpusave(int flags);
void bcopyb(const void *from, void *to, size_t len);
void busdma_swi(void);
+bool cpu_mwait_usable(void);
void cpu_probe_amdc1e(void);
void cpu_setregs(void);
void cpu_switch_load_gs(void) __asm(__STRING(cpu_switch_load_gs));
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index c3dd792..2c7fe2e 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -943,7 +943,8 @@ fail:
#endif
racct_proc_exit(newproc);
fail1:
- crfree(proc_set_cred(newproc, NULL));
+ crfree(newproc->p_ucred);
+ newproc->p_ucred = NULL;
fail2:
if (vm2 != NULL)
vmspace_free(vm2);
diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c
index aef1e4e..ff5b106 100644
--- a/sys/kern/kern_malloc.c
+++ b/sys/kern/kern_malloc.c
@@ -665,13 +665,15 @@ reallocf(void *addr, unsigned long size, struct malloc_type *mtp, int flags)
}
/*
- * Wake the page daemon when we exhaust KVA. It will call the lowmem handler
- * and uma_reclaim() callbacks in a context that is safe.
+ * Wake the uma reclamation pagedaemon thread when we exhaust KVA. It
+ * will call the lowmem handler and uma_reclaim() callbacks in a
+ * context that is safe.
*/
static void
kmem_reclaim(vmem_t *vm, int flags)
{
+ uma_reclaim_wakeup();
pagedaemon_wakeup();
}
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 1d5ba1a..154c250 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -3371,8 +3371,6 @@ coredump(struct thread *td)
len = MAXPATHLEN * 2 + sizeof(comm_name) - 1 +
sizeof(' ') + sizeof(core_name) - 1;
data = malloc(len, M_TEMP, M_WAITOK);
- if (data == NULL)
- goto out;
if (vn_fullpath_global(td, p->p_textvp, &fullpath, &freepath) != 0)
goto out;
if (!coredump_sanitise_path(fullpath))
diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c
index 0a93dbd..c7c0ee4 100644
--- a/sys/kern/kern_thread.c
+++ b/sys/kern/kern_thread.c
@@ -759,6 +759,29 @@ stopme:
PROC_LOCK(p);
PROC_SLOCK(p);
}
+ } else if (mode == SINGLE_BOUNDARY) {
+ /*
+ * Wait until all suspended threads are removed from
+ * the processors. The thread_suspend_check()
+ * increments p_boundary_count while it is still
+ * running, which makes it possible for the execve()
+ * to destroy vmspace while our other threads are
+ * still using the address space.
+ *
+ * We lock the thread, which is only allowed to
+ * succeed after context switch code finished using
+ * the address space.
+ */
+ FOREACH_THREAD_IN_PROC(p, td2) {
+ if (td2 == td)
+ continue;
+ thread_lock(td2);
+ KASSERT((td2->td_flags & TDF_BOUNDARY) != 0,
+ ("td %p not on boundary", td2));
+ KASSERT(TD_IS_SUSPENDED(td2),
+ ("td %p is not suspended", td2));
+ thread_unlock(td2);
+ }
}
PROC_SUNLOCK(p);
return (0);
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index a1a7915..b77d476 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -813,6 +813,7 @@ m_dup(struct mbuf *m, int how)
}
if ((n->m_flags & M_EXT) == 0)
nsize = MHLEN;
+ n->m_flags &= ~M_RDONLY;
}
n->m_len = 0;
diff --git a/sys/net/if_me.c b/sys/net/if_me.c
index a00bdd2..56fe4d5 100644
--- a/sys/net/if_me.c
+++ b/sys/net/if_me.c
@@ -477,7 +477,7 @@ me_check_nesting(struct ifnet *ifp, struct mbuf *m)
count = 1;
mtag = NULL;
- while ((mtag = m_tag_locate(m, MTAG_ME, 0, NULL)) != NULL) {
+ while ((mtag = m_tag_locate(m, MTAG_ME, 0, mtag)) != NULL) {
if (*(struct ifnet **)(mtag + 1) == ifp) {
log(LOG_NOTICE, "%s: loop detected\n", ifp->if_xname);
return (EIO);
diff --git a/sys/netinet/sctp_auth.c b/sys/netinet/sctp_auth.c
index 8ce2aab..7c2e194 100644
--- a/sys/netinet/sctp_auth.c
+++ b/sys/netinet/sctp_auth.c
@@ -576,13 +576,12 @@ sctp_auth_key_release(struct sctp_tcb *stcb, uint16_t key_id, int so_locked
/* decrement the ref count */
if (skey) {
- sctp_free_sharedkey(skey);
SCTPDBG(SCTP_DEBUG_AUTH2,
"%s: stcb %p key %u refcount release to %d\n",
__FUNCTION__, (void *)stcb, key_id, skey->refcount);
/* see if a notification should be generated */
- if ((skey->refcount <= 1) && (skey->deactivated)) {
+ if ((skey->refcount <= 2) && (skey->deactivated)) {
/* notify ULP that key is no longer used */
sctp_ulp_notify(SCTP_NOTIFY_AUTH_FREE_KEY, stcb,
key_id, 0, so_locked);
@@ -590,6 +589,7 @@ sctp_auth_key_release(struct sctp_tcb *stcb, uint16_t key_id, int so_locked
"%s: stcb %p key %u no longer used, %d\n",
__FUNCTION__, (void *)stcb, key_id, skey->refcount);
}
+ sctp_free_sharedkey(skey);
}
}
diff --git a/sys/netinet6/ip6_ipsec.c b/sys/netinet6/ip6_ipsec.c
index e6e16ed..d7f08e9 100644
--- a/sys/netinet6/ip6_ipsec.c
+++ b/sys/netinet6/ip6_ipsec.c
@@ -31,7 +31,7 @@
__FBSDID("$FreeBSD$");
#include "opt_inet.h"
-#include "opt_inet6.h"
+#include "opt_sctp.h"
#include "opt_ipsec.h"
#include <sys/param.h>
@@ -58,10 +58,12 @@ __FBSDID("$FreeBSD$");
#include <netinet/in_pcb.h>
#include <netinet/ip_var.h>
#include <netinet/ip_options.h>
+#ifdef SCTP
+#include <netinet/sctp_crc32.h>
+#endif
#include <machine/in_cksum.h>
-#ifdef IPSEC
#include <netipsec/ipsec.h>
#include <netipsec/ipsec6.h>
#include <netipsec/xform.h>
@@ -71,16 +73,12 @@ __FBSDID("$FreeBSD$");
#else
#define KEYDEBUG(lev,arg)
#endif
-#endif /*IPSEC*/
#include <netinet6/ip6_ipsec.h>
#include <netinet6/ip6_var.h>
extern struct protosw inet6sw[];
-
-#ifdef INET6
-#ifdef IPSEC
#ifdef IPSEC_FILTERTUNNEL
static VNET_DEFINE(int, ip6_ipsec6_filtertunnel) = 1;
#else
@@ -92,8 +90,6 @@ SYSCTL_DECL(_net_inet6_ipsec6);
SYSCTL_INT(_net_inet6_ipsec6, OID_AUTO, filtertunnel,
CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_ipsec6_filtertunnel), 0,
"If set filter packets from an IPsec tunnel.");
-#endif /* IPSEC */
-#endif /* INET6 */
/*
* Check if we have to jump over firewall processing for this packet.
@@ -103,16 +99,14 @@ SYSCTL_INT(_net_inet6_ipsec6, OID_AUTO, filtertunnel,
int
ip6_ipsec_filtertunnel(struct mbuf *m)
{
-#ifdef IPSEC
/*
* Bypass packet filtering for packets previously handled by IPsec.
*/
if (!V_ip6_ipsec6_filtertunnel &&
m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL) != NULL)
- return 1;
-#endif
- return 0;
+ return (1);
+ return (0);
}
/*
@@ -125,11 +119,7 @@ int
ip6_ipsec_fwd(struct mbuf *m)
{
-#ifdef IPSEC
return (ipsec6_in_reject(m, NULL));
-#else
- return (0);
-#endif /* !IPSEC */
}
/*
@@ -143,7 +133,6 @@ int
ip6_ipsec_input(struct mbuf *m, int nxt)
{
-#ifdef IPSEC
/*
* enforce IPsec policy checking if we are seeing last header.
* note that we do not visit this with protocols with pcb layer
@@ -151,7 +140,6 @@ ip6_ipsec_input(struct mbuf *m, int nxt)
*/
if ((inet6sw[ip6_protox[nxt]].pr_flags & PR_LASTHDR) != 0)
return (ipsec6_in_reject(m, NULL));
-#endif /* IPSEC */
return (0);
}
@@ -164,7 +152,6 @@ ip6_ipsec_input(struct mbuf *m, int nxt)
int
ip6_ipsec_output(struct mbuf **m, struct inpcb *inp, int *error)
{
-#ifdef IPSEC
struct secpolicy *sp;
/*
@@ -257,9 +244,7 @@ reinjected:
bad:
if (sp != NULL)
KEY_FREESP(&sp);
- return 1;
-#endif /* IPSEC */
- return 0;
+ return (1);
}
#if 0
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
index eda02d9..d667903 100644
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -2900,14 +2900,6 @@ ip6_mloopback(struct ifnet *ifp, struct mbuf *m, struct sockaddr_in6 *dst)
if (copym == NULL)
return;
}
-
-#ifdef DIAGNOSTIC
- if (copym->m_len < sizeof(*ip6)) {
- m_freem(copym);
- return;
- }
-#endif
-
ip6 = mtod(copym, struct ip6_hdr *);
/*
* clear embedded scope identifiers if necessary.
@@ -2915,7 +2907,11 @@ ip6_mloopback(struct ifnet *ifp, struct mbuf *m, struct sockaddr_in6 *dst)
*/
in6_clearscope(&ip6->ip6_src);
in6_clearscope(&ip6->ip6_dst);
-
+ if (copym->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6) {
+ copym->m_pkthdr.csum_flags |= CSUM_DATA_VALID_IPV6 |
+ CSUM_PSEUDO_HDR;
+ copym->m_pkthdr.csum_data = 0xffff;
+ }
(void)if_simloop(ifp, copym, dst->sin6_family, 0);
}
diff --git a/sys/sys/param.h b/sys/sys/param.h
index bc722df..cbc2901 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -58,7 +58,7 @@
* in the range 5 to 9.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 1100072 /* Master, propagated to newvers */
+#define __FreeBSD_version 1100073 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
diff --git a/sys/sys/pmc.h b/sys/sys/pmc.h
index 34d9c34..cc67d37 100644
--- a/sys/sys/pmc.h
+++ b/sys/sys/pmc.h
@@ -998,7 +998,8 @@ extern struct pmc_cpu **pmc_pcpu;
/* driver statistics */
extern struct pmc_op_getdriverstats pmc_stats;
-#if defined(DEBUG)
+#if defined(HWPMC_DEBUG)
+#include <sys/ktr.h>
/* debug flags, major flag groups */
struct pmc_debugflags {
@@ -1015,14 +1016,42 @@ struct pmc_debugflags {
extern struct pmc_debugflags pmc_debugflags;
+#define KTR_PMC KTR_SUBSYS
+
#define PMC_DEBUG_STRSIZE 128
#define PMC_DEBUG_DEFAULT_FLAGS { 0, 0, 0, 0, 0, 0, 0, 0 }
-#define PMCDBG(M,N,L,F,...) do { \
+#define PMCDBG0(M, N, L, F) do { \
if (pmc_debugflags.pdb_ ## M & (1 << PMC_DEBUG_MIN_ ## N)) \
- printf(#M ":" #N ":" #L ": " F "\n", __VA_ARGS__); \
+ CTR0(KTR_PMC, #M ":" #N ":" #L ": " F); \
} while (0)
-
+#define PMCDBG1(M, N, L, F, p1) do { \
+ if (pmc_debugflags.pdb_ ## M & (1 << PMC_DEBUG_MIN_ ## N)) \
+ CTR1(KTR_PMC, #M ":" #N ":" #L ": " F, p1); \
+} while (0)
+#define PMCDBG2(M, N, L, F, p1, p2) do { \
+ if (pmc_debugflags.pdb_ ## M & (1 << PMC_DEBUG_MIN_ ## N)) \
+ CTR2(KTR_PMC, #M ":" #N ":" #L ": " F, p1, p2); \
+} while (0)
+#define PMCDBG3(M, N, L, F, p1, p2, p3) do { \
+ if (pmc_debugflags.pdb_ ## M & (1 << PMC_DEBUG_MIN_ ## N)) \
+ CTR3(KTR_PMC, #M ":" #N ":" #L ": " F, p1, p2, p3); \
+} while (0)
+#define PMCDBG4(M, N, L, F, p1, p2, p3, p4) do { \
+ if (pmc_debugflags.pdb_ ## M & (1 << PMC_DEBUG_MIN_ ## N)) \
+ CTR4(KTR_PMC, #M ":" #N ":" #L ": " F, p1, p2, p3, p4);\
+} while (0)
+#define PMCDBG5(M, N, L, F, p1, p2, p3, p4, p5) do { \
+ if (pmc_debugflags.pdb_ ## M & (1 << PMC_DEBUG_MIN_ ## N)) \
+ CTR5(KTR_PMC, #M ":" #N ":" #L ": " F, p1, p2, p3, p4, \
+ p5); \
+} while (0)
+#define PMCDBG6(M, N, L, F, p1, p2, p3, p4, p5, p6) do { \
+ if (pmc_debugflags.pdb_ ## M & (1 << PMC_DEBUG_MIN_ ## N)) \
+ CTR6(KTR_PMC, #M ":" #N ":" #L ": " F, p1, p2, p3, p4, \
+ p5, p6); \
+} while (0)
+
/* Major numbers */
#define PMC_DEBUG_MAJ_CPU 0 /* cpu switches */
#define PMC_DEBUG_MAJ_CSW 1 /* context switches */
@@ -1088,7 +1117,13 @@ extern struct pmc_debugflags pmc_debugflags;
#define PMC_DEBUG_MIN_CLO 12 /* close */
#else
-#define PMCDBG(M,N,L,F,...) /* nothing */
+#define PMCDBG0(M, N, L, F) /* nothing */
+#define PMCDBG1(M, N, L, F, p1)
+#define PMCDBG2(M, N, L, F, p1, p2)
+#define PMCDBG3(M, N, L, F, p1, p2, p3)
+#define PMCDBG4(M, N, L, F, p1, p2, p3, p4)
+#define PMCDBG5(M, N, L, F, p1, p2, p3, p4, p5)
+#define PMCDBG6(M, N, L, F, p1, p2, p3, p4, p5, p6)
#endif
/* declare a dedicated memory pool */
diff --git a/sys/vm/default_pager.c b/sys/vm/default_pager.c
index 26326a5..98dee45 100644
--- a/sys/vm/default_pager.c
+++ b/sys/vm/default_pager.c
@@ -113,6 +113,7 @@ default_pager_dealloc(object)
/*
* OBJT_DEFAULT objects have no special resources allocated to them.
*/
+ object->type = OBJT_DEAD;
}
/*
diff --git a/sys/vm/device_pager.c b/sys/vm/device_pager.c
index d05ea33..33fba4e 100644
--- a/sys/vm/device_pager.c
+++ b/sys/vm/device_pager.c
@@ -254,6 +254,8 @@ dev_pager_dealloc(object)
!= NULL)
dev_pager_free_page(object, m);
}
+ object->handle = NULL;
+ object->type = OBJT_DEAD;
}
static int
diff --git a/sys/vm/phys_pager.c b/sys/vm/phys_pager.c
index 9e98006..885a451 100644
--- a/sys/vm/phys_pager.c
+++ b/sys/vm/phys_pager.c
@@ -131,6 +131,8 @@ phys_pager_dealloc(vm_object_t object)
mtx_unlock(&phys_pager_mtx);
VM_OBJECT_WLOCK(object);
}
+ object->handle = NULL;
+ object->type = OBJT_DEAD;
}
/*
diff --git a/sys/vm/sg_pager.c b/sys/vm/sg_pager.c
index e35741e..23ebd3a 100644
--- a/sys/vm/sg_pager.c
+++ b/sys/vm/sg_pager.c
@@ -130,6 +130,8 @@ sg_pager_dealloc(vm_object_t object)
sg = object->handle;
sglist_free(sg);
+ object->handle = NULL;
+ object->type = OBJT_DEAD;
}
static int
diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index 9a83989..3005491 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -697,6 +697,8 @@ swap_pager_dealloc(vm_object_t object)
* if paging is still in progress on some objects.
*/
swp_pager_meta_free_all(object);
+ object->handle = NULL;
+ object->type = OBJT_DEAD;
}
/************************************************************************
diff --git a/sys/vm/uma.h b/sys/vm/uma.h
index df6cc5c..d3e0658 100644
--- a/sys/vm/uma.h
+++ b/sys/vm/uma.h
@@ -690,4 +690,7 @@ struct uma_percpu_stat {
uint64_t _ups_reserved[5]; /* Reserved. */
};
+void uma_reclaim_wakeup(void);
+void uma_reclaim_worker(void *);
+
#endif /* _VM_UMA_H_ */
diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c
index 4ff177f..d1573e6 100644
--- a/sys/vm/uma_core.c
+++ b/sys/vm/uma_core.c
@@ -3222,16 +3222,17 @@ uma_find_refcnt(uma_zone_t zone, void *item)
}
/* See uma.h */
-void
-uma_reclaim(void)
+static void
+uma_reclaim_locked(bool kmem_danger)
{
+
#ifdef UMA_DEBUG
printf("UMA: vm asked us to release pages!\n");
#endif
- sx_xlock(&uma_drain_lock);
+ sx_assert(&uma_drain_lock, SA_XLOCKED);
bucket_enable();
zone_foreach(zone_drain);
- if (vm_page_count_min()) {
+ if (vm_page_count_min() || kmem_danger) {
cache_drain_safe(NULL);
zone_foreach(zone_drain);
}
@@ -3243,9 +3244,42 @@ uma_reclaim(void)
zone_drain(slabzone);
zone_drain(slabrefzone);
bucket_zone_drain();
+}
+
+void
+uma_reclaim(void)
+{
+
+ sx_xlock(&uma_drain_lock);
+ uma_reclaim_locked(false);
sx_xunlock(&uma_drain_lock);
}
+static int uma_reclaim_needed;
+
+void
+uma_reclaim_wakeup(void)
+{
+
+ uma_reclaim_needed = 1;
+ wakeup(&uma_reclaim_needed);
+}
+
+void
+uma_reclaim_worker(void *arg __unused)
+{
+
+ sx_xlock(&uma_drain_lock);
+ for (;;) {
+ sx_sleep(&uma_reclaim_needed, &uma_drain_lock, PVM,
+ "umarcl", 0);
+ if (uma_reclaim_needed) {
+ uma_reclaim_needed = 0;
+ uma_reclaim_locked(true);
+ }
+ }
+}
+
/* See uma.h */
int
uma_zone_exhausted(uma_zone_t zone)
diff --git a/sys/vm/vm_meter.c b/sys/vm/vm_meter.c
index 4ec2613..865be71 100644
--- a/sys/vm/vm_meter.c
+++ b/sys/vm/vm_meter.c
@@ -111,14 +111,7 @@ vmtotal(SYSCTL_HANDLER_ARGS)
*/
mtx_lock(&vm_object_list_mtx);
TAILQ_FOREACH(object, &vm_object_list, object_list) {
- if (!VM_OBJECT_TRYWLOCK(object)) {
- /*
- * Avoid a lock-order reversal. Consequently,
- * the reported number of active pages may be
- * greater than the actual number.
- */
- continue;
- }
+ VM_OBJECT_WLOCK(object);
vm_object_clear_flag(object, OBJ_ACTIVE);
VM_OBJECT_WUNLOCK(object);
}
@@ -196,10 +189,9 @@ vmtotal(SYSCTL_HANDLER_ARGS)
mtx_lock(&vm_object_list_mtx);
TAILQ_FOREACH(object, &vm_object_list, object_list) {
/*
- * Perform unsynchronized reads on the object to avoid
- * a lock-order reversal. In this case, the lack of
- * synchronization should not impair the accuracy of
- * the reported statistics.
+ * Perform unsynchronized reads on the object. In
+ * this case, the lack of synchronization should not
+ * impair the accuracy of the reported statistics.
*/
if ((object->flags & OBJ_FICTITIOUS) != 0) {
/*
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index a1d6701..78cea70 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -166,6 +166,8 @@ vm_object_zdtor(void *mem, int size, void *arg)
vm_object_t object;
object = (vm_object_t)mem;
+ KASSERT(object->ref_count == 0,
+ ("object %p ref_count = %d", object, object->ref_count));
KASSERT(TAILQ_EMPTY(&object->memq),
("object %p has resident pages in its memq", object));
KASSERT(vm_radix_is_empty(&object->rtree),
@@ -187,6 +189,9 @@ vm_object_zdtor(void *mem, int size, void *arg)
KASSERT(object->shadow_count == 0,
("object %p shadow_count = %d",
object, object->shadow_count));
+ KASSERT(object->type == OBJT_DEAD,
+ ("object %p has non-dead type %d",
+ object, object->type));
}
#endif
@@ -199,6 +204,8 @@ vm_object_zinit(void *mem, int size, int flags)
rw_init_flags(&object->lock, "vm object", RW_DUPOK | RW_NEW);
/* These are true for any object that has been freed */
+ object->type = OBJT_DEAD;
+ object->ref_count = 0;
object->rtree.rt_root = 0;
object->rtree.rt_flags = 0;
object->paging_in_progress = 0;
@@ -206,6 +213,10 @@ vm_object_zinit(void *mem, int size, int flags)
object->shadow_count = 0;
object->cache.rt_root = 0;
object->cache.rt_flags = 0;
+
+ mtx_lock(&vm_object_list_mtx);
+ TAILQ_INSERT_TAIL(&vm_object_list, object, object_list);
+ mtx_unlock(&vm_object_list_mtx);
return (0);
}
@@ -252,10 +263,6 @@ _vm_object_allocate(objtype_t type, vm_pindex_t size, vm_object_t object)
#if VM_NRESERVLEVEL > 0
LIST_INIT(&object->rvq);
#endif
-
- mtx_lock(&vm_object_list_mtx);
- TAILQ_INSERT_TAIL(&vm_object_list, object, object_list);
- mtx_unlock(&vm_object_list_mtx);
}
/*
@@ -671,19 +678,9 @@ vm_object_destroy(vm_object_t object)
{
/*
- * Remove the object from the global object list.
- */
- mtx_lock(&vm_object_list_mtx);
- TAILQ_REMOVE(&vm_object_list, object, object_list);
- mtx_unlock(&vm_object_list_mtx);
-
- /*
* Release the allocation charge.
*/
if (object->cred != NULL) {
- KASSERT(object->type == OBJT_DEFAULT ||
- object->type == OBJT_SWAP,
- ("%s: non-swap obj %p has cred", __func__, object));
swap_release_by_cred(object->charge, object->cred);
object->charge = 0;
crfree(object->cred);
@@ -788,6 +785,10 @@ vm_object_terminate(vm_object_t object)
if (__predict_false(!vm_object_cache_is_empty(object)))
vm_page_cache_free(object, 0, 0);
+ KASSERT(object->cred == NULL || object->type == OBJT_DEFAULT ||
+ object->type == OBJT_SWAP,
+ ("%s: non-swap obj %p has cred", __func__, object));
+
/*
* Let the pager know object is dead.
*/
@@ -1803,6 +1804,8 @@ vm_object_collapse(vm_object_t object)
KASSERT(backing_object->ref_count == 1, (
"backing_object %p was somehow re-referenced during collapse!",
backing_object));
+ backing_object->type = OBJT_DEAD;
+ backing_object->ref_count = 0;
VM_OBJECT_WUNLOCK(backing_object);
vm_object_destroy(backing_object);
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c
index 872ffd8..2f57579 100644
--- a/sys/vm/vm_pageout.c
+++ b/sys/vm/vm_pageout.c
@@ -1724,8 +1724,9 @@ vm_pageout_init(void)
static void
vm_pageout(void)
{
+ int error;
#if MAXMEMDOM > 1
- int error, i;
+ int i;
#endif
swap_pager_swap_init();
@@ -1739,6 +1740,10 @@ vm_pageout(void)
}
}
#endif
+ error = kthread_add(uma_reclaim_worker, NULL, curproc, NULL,
+ 0, 0, "uma");
+ if (error != 0)
+ panic("starting uma_reclaim helper, error %d\n", error);
vm_pageout_worker((void *)(uintptr_t)0);
}
diff --git a/sys/vm/vm_phys.c b/sys/vm/vm_phys.c
index 5c33be4..71fadd7 100644
--- a/sys/vm/vm_phys.c
+++ b/sys/vm/vm_phys.c
@@ -71,6 +71,7 @@ _Static_assert(sizeof(long) * NBBY >= VM_PHYSSEG_MAX,
"Too many physsegs.");
struct mem_affinity *mem_affinity;
+int *mem_locality;
int vm_ndomains = 1;
@@ -140,6 +141,10 @@ static int sysctl_vm_phys_segs(SYSCTL_HANDLER_ARGS);
SYSCTL_OID(_vm, OID_AUTO, phys_segs, CTLTYPE_STRING | CTLFLAG_RD,
NULL, 0, sysctl_vm_phys_segs, "A", "Phys Seg Info");
+static int sysctl_vm_phys_locality(SYSCTL_HANDLER_ARGS);
+SYSCTL_OID(_vm, OID_AUTO, phys_locality, CTLTYPE_STRING | CTLFLAG_RD,
+ NULL, 0, sysctl_vm_phys_locality, "A", "Phys Locality Info");
+
SYSCTL_INT(_vm, OID_AUTO, ndomains, CTLFLAG_RD,
&vm_ndomains, 0, "Number of physical memory domains available.");
@@ -297,6 +302,48 @@ sysctl_vm_phys_segs(SYSCTL_HANDLER_ARGS)
return (error);
}
+/*
+ * Return affinity, or -1 if there's no affinity information.
+ */
+static int
+vm_phys_mem_affinity(int f, int t)
+{
+
+ if (mem_locality == NULL)
+ return (-1);
+ if (f >= vm_ndomains || t >= vm_ndomains)
+ return (-1);
+ return (mem_locality[f * vm_ndomains + t]);
+}
+
+/*
+ * Outputs the VM locality table.
+ */
+static int
+sysctl_vm_phys_locality(SYSCTL_HANDLER_ARGS)
+{
+ struct sbuf sbuf;
+ int error, i, j;
+
+ error = sysctl_wire_old_buffer(req, 0);
+ if (error != 0)
+ return (error);
+ sbuf_new_for_sysctl(&sbuf, NULL, 128, req);
+
+ sbuf_printf(&sbuf, "\n");
+
+ for (i = 0; i < vm_ndomains; i++) {
+ sbuf_printf(&sbuf, "%d: ", i);
+ for (j = 0; j < vm_ndomains; j++) {
+ sbuf_printf(&sbuf, "%d ", vm_phys_mem_affinity(i, j));
+ }
+ sbuf_printf(&sbuf, "\n");
+ }
+ error = sbuf_finish(&sbuf);
+ sbuf_delete(&sbuf);
+ return (error);
+}
+
static void
vm_freelist_add(struct vm_freelist *fl, vm_page_t m, int order, int tail)
{
diff --git a/sys/vm/vm_phys.h b/sys/vm/vm_phys.h
index 8f3e847..575b93c 100644
--- a/sys/vm/vm_phys.h
+++ b/sys/vm/vm_phys.h
@@ -61,6 +61,7 @@ struct vm_phys_seg {
};
extern struct mem_affinity *mem_affinity;
+extern int *mem_locality;
extern int vm_ndomains;
extern struct vm_phys_seg vm_phys_segs[];
extern int vm_phys_nsegs;
diff --git a/sys/x86/acpica/srat.c b/sys/x86/acpica/srat.c
index 8d2a741..e908279 100644
--- a/sys/x86/acpica/srat.c
+++ b/sys/x86/acpica/srat.c
@@ -64,9 +64,97 @@ static vm_paddr_t srat_physaddr;
static int vm_domains[VM_PHYSSEG_MAX];
+static ACPI_TABLE_SLIT *slit;
+static vm_paddr_t slit_physaddr;
+static int vm_locality_table[MAXMEMDOM * MAXMEMDOM];
+
static void srat_walk_table(acpi_subtable_handler *handler, void *arg);
/*
+ * SLIT parsing.
+ */
+
+static void
+slit_parse_table(ACPI_TABLE_SLIT *s)
+{
+ int i, j;
+ int i_domain, j_domain;
+ int offset = 0;
+ uint8_t e;
+
+ /*
+ * This maps the SLIT data into the VM-domain centric view.
+ * There may be sparse entries in the PXM namespace, so
+ * remap them to a VM-domain ID and if it doesn't exist,
+ * skip it.
+ *
+ * It should result in a packed 2d array of VM-domain
+ * locality information entries.
+ */
+
+ if (bootverbose)
+ printf("SLIT.Localities: %d\n", (int) s->LocalityCount);
+ for (i = 0; i < s->LocalityCount; i++) {
+ i_domain = acpi_map_pxm_to_vm_domainid(i);
+ if (i_domain < 0)
+ continue;
+
+ if (bootverbose)
+ printf("%d: ", i);
+ for (j = 0; j < s->LocalityCount; j++) {
+ j_domain = acpi_map_pxm_to_vm_domainid(j);
+ if (j_domain < 0)
+ continue;
+ e = s->Entry[i * s->LocalityCount + j];
+ if (bootverbose)
+ printf("%d ", (int) e);
+ /* 255 == "no locality information" */
+ if (e == 255)
+ vm_locality_table[offset] = -1;
+ else
+ vm_locality_table[offset] = e;
+ offset++;
+ }
+ if (bootverbose)
+ printf("\n");
+ }
+}
+
+/*
+ * Look for an ACPI System Locality Distance Information Table ("SLIT")
+ */
+static int
+parse_slit(void)
+{
+
+ if (resource_disabled("slit", 0)) {
+ return (-1);
+ }
+
+ slit_physaddr = acpi_find_table(ACPI_SIG_SLIT);
+ if (slit_physaddr == 0) {
+ return (-1);
+ }
+
+ /*
+ * Make a pass over the table to populate the cpus[] and
+ * mem_info[] tables.
+ */
+ slit = acpi_map_table(slit_physaddr, ACPI_SIG_SLIT);
+ slit_parse_table(slit);
+ acpi_unmap_table(slit);
+ slit = NULL;
+
+ /* Tell the VM about it! */
+ mem_locality = vm_locality_table;
+ return (0);
+}
+
+/*
+ * SRAT parsing.
+ */
+
+/*
* Returns true if a memory range overlaps with at least one range in
* phys_avail[].
*/
@@ -301,17 +389,17 @@ renumber_domains(void)
/*
* Look for an ACPI System Resource Affinity Table ("SRAT")
*/
-static void
-parse_srat(void *dummy)
+static int
+parse_srat(void)
{
int error;
if (resource_disabled("srat", 0))
- return;
+ return (-1);
srat_physaddr = acpi_find_table(ACPI_SIG_SRAT);
if (srat_physaddr == 0)
- return;
+ return (-1);
/*
* Make a pass over the table to populate the cpus[] and
@@ -325,13 +413,39 @@ parse_srat(void *dummy)
if (error || check_domains() != 0 || check_phys_avail() != 0 ||
renumber_domains() != 0) {
srat_physaddr = 0;
- return;
+ return (-1);
}
/* Point vm_phys at our memory affinity table. */
mem_affinity = mem_info;
+
+ return (0);
+}
+
+static void
+init_mem_locality(void)
+{
+ int i;
+
+ /*
+ * For now, assume 255 == "no locality information for
+ * this pairing.
+ */
+ for (i = 0; i < MAXMEMDOM * MAXMEMDOM; i++)
+ vm_locality_table[i] = -1;
+}
+
+static void
+parse_acpi_tables(void *dummy)
+{
+
+ if (parse_srat() < 0)
+ return;
+ init_mem_locality();
+ (void) parse_slit();
}
-SYSINIT(parse_srat, SI_SUB_VM - 1, SI_ORDER_FIRST, parse_srat, NULL);
+SYSINIT(parse_acpi_tables, SI_SUB_VM - 1, SI_ORDER_FIRST, parse_acpi_tables,
+ NULL);
static void
srat_walk_table(acpi_subtable_handler *handler, void *arg)
diff --git a/sys/x86/include/acpica_machdep.h b/sys/x86/include/acpica_machdep.h
index 46080c0..136285c 100644
--- a/sys/x86/include/acpica_machdep.h
+++ b/sys/x86/include/acpica_machdep.h
@@ -74,6 +74,7 @@ enum intr_polarity;
void acpi_SetDefaultIntrModel(int model);
void acpi_cpu_c1(void);
+void acpi_cpu_idle_mwait(uint32_t mwait_hint);
void *acpi_map_table(vm_paddr_t pa, const char *sig);
void acpi_unmap_table(void *table);
vm_paddr_t acpi_find_table(const char *sig);
diff --git a/sys/x86/include/specialreg.h b/sys/x86/include/specialreg.h
index a771fff..6c849ff 100644
--- a/sys/x86/include/specialreg.h
+++ b/sys/x86/include/specialreg.h
@@ -53,6 +53,7 @@
#define CR0_CD 0x40000000 /* Cache Disable */
#define CR3_PCID_SAVE 0x8000000000000000
+#define CR3_PCID_MASK 0xfff
/*
* Bits in PPro special registers
diff --git a/sys/x86/x86/cpu_machdep.c b/sys/x86/x86/cpu_machdep.c
index f8d1f08..7925713 100644
--- a/sys/x86/x86/cpu_machdep.c
+++ b/sys/x86/x86/cpu_machdep.c
@@ -90,6 +90,7 @@ __FBSDID("$FreeBSD$");
#ifdef SMP
#include <machine/smp.h>
#endif
+#include <x86/acpica_machdep.h>
#include <vm/vm.h>
#include <vm/vm_extern.h>
@@ -121,6 +122,27 @@ cpu_flush_dcache(void *ptr, size_t len)
/* Not applicable */
}
+void
+acpi_cpu_c1(void)
+{
+
+ __asm __volatile("sti; hlt");
+}
+
+void
+acpi_cpu_idle_mwait(uint32_t mwait_hint)
+{
+ int *state;
+
+ state = (int *)PCPU_PTR(monitorbuf);
+ /*
+ * XXXKIB. Software coordination mode should be supported,
+ * but all Intel CPUs provide hardware coordination.
+ */
+ cpu_monitor(state, 0, 0);
+ cpu_mwait(MWAIT_INTRBREAK, mwait_hint);
+}
+
/* Get current clock frequency for the given cpu id. */
int
cpu_est_clockrate(int cpu_id, uint64_t *rate)
@@ -194,6 +216,15 @@ cpu_halt(void)
halt();
}
+bool
+cpu_mwait_usable(void)
+{
+
+ return ((cpu_feature2 & CPUID2_MON) != 0 && ((cpu_mon_mwait_flags &
+ (CPUID5_MON_MWAIT_EXT | CPUID5_MWAIT_INTRBREAK)) ==
+ (CPUID5_MON_MWAIT_EXT | CPUID5_MWAIT_INTRBREAK)));
+}
+
void (*cpu_idle_hook)(sbintime_t) = NULL; /* ACPI idle hook. */
static int cpu_ident_amdc1e = 0; /* AMD C1E supported. */
static int idle_mwait = 1; /* Use MONITOR/MWAIT for short idle. */
@@ -220,7 +251,7 @@ cpu_idle_acpi(sbintime_t sbt)
else if (cpu_idle_hook)
cpu_idle_hook(sbt);
else
- __asm __volatile("sti; hlt");
+ acpi_cpu_c1();
*state = STATE_RUNNING;
}
#endif /* !PC98 */
@@ -253,7 +284,7 @@ cpu_idle_hlt(sbintime_t sbt)
if (sched_runnable())
enable_intr();
else
- __asm __volatile("sti; hlt");
+ acpi_cpu_c1();
*state = STATE_RUNNING;
}
diff --git a/sys/x86/xen/xen_apic.c b/sys/x86/xen/xen_apic.c
index c742920..a65f3b5 100644
--- a/sys/x86/xen/xen_apic.c
+++ b/sys/x86/xen/xen_apic.c
@@ -423,31 +423,29 @@ xen_invltlb(void *arg)
#ifdef __amd64__
static int
-xen_invltlb_pcid(void *arg)
+xen_invltlb_invpcid(void *arg)
{
- invltlb_pcid_handler();
+ invltlb_invpcid_handler();
return (FILTER_HANDLED);
}
-#endif
static int
-xen_invlpg(void *arg)
+xen_invltlb_pcid(void *arg)
{
- invlpg_handler();
+ invltlb_pcid_handler();
return (FILTER_HANDLED);
}
+#endif
-#ifdef __amd64__
static int
-xen_invlpg_pcid(void *arg)
+xen_invlpg(void *arg)
{
- invlpg_pcid_handler();
+ invlpg_handler();
return (FILTER_HANDLED);
}
-#endif
static int
xen_invlrng(void *arg)
@@ -532,8 +530,8 @@ xen_setup_cpus(void)
#ifdef __amd64__
if (pmap_pcid_enabled) {
- xen_ipis[IPI_TO_IDX(IPI_INVLTLB)].filter = xen_invltlb_pcid;
- xen_ipis[IPI_TO_IDX(IPI_INVLPG)].filter = xen_invlpg_pcid;
+ xen_ipis[IPI_TO_IDX(IPI_INVLTLB)].filter = invpcid_works ?
+ xen_invltlb_invpcid : xen_invltlb_pcid;
}
#endif
CPU_FOREACH(i)
diff --git a/sys/x86/xen/xenpv.c b/sys/x86/xen/xenpv.c
index bdda883..2e4a9fe 100644
--- a/sys/x86/xen/xenpv.c
+++ b/sys/x86/xen/xenpv.c
@@ -33,11 +33,33 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/pcpu.h>
+#include <sys/rman.h>
#include <sys/smp.h>
+#include <vm/vm.h>
+#include <vm/vm_page.h>
+#include <vm/vm_param.h>
+#include <vm/vm_phys.h>
+
#include <xen/xen-os.h>
#include <xen/gnttab.h>
+#include "xenmem_if.h"
+
+/*
+ * Allocate unused physical memory above 4GB in order to map memory
+ * from foreign domains. We use memory starting at 4GB in order to
+ * prevent clashes with MMIO/ACPI regions.
+ *
+ * Since this is not possible on i386 just use any available memory
+ * chunk and hope we don't clash with anything else.
+ */
+#ifdef __amd64__
+#define LOW_MEM_LIMIT 0x100000000ul
+#else
+#define LOW_MEM_LIMIT 0
+#endif
+
static devclass_t xenpv_devclass;
static void
@@ -85,6 +107,42 @@ xenpv_attach(device_t dev)
return (0);
}
+static struct resource *
+xenpv_alloc_physmem(device_t dev, device_t child, int *res_id, size_t size)
+{
+ struct resource *res;
+ vm_paddr_t phys_addr;
+ int error;
+
+ res = bus_alloc_resource(child, SYS_RES_MEMORY, res_id, LOW_MEM_LIMIT,
+ ~0ul, size, RF_ACTIVE);
+ if (res == NULL)
+ return (NULL);
+
+ phys_addr = rman_get_start(res);
+ error = vm_phys_fictitious_reg_range(phys_addr, phys_addr + size,
+ VM_MEMATTR_DEFAULT);
+ if (error) {
+ bus_release_resource(child, SYS_RES_MEMORY, *res_id, res);
+ return (NULL);
+ }
+
+ return (res);
+}
+
+static int
+xenpv_free_physmem(device_t dev, device_t child, int res_id, struct resource *res)
+{
+ vm_paddr_t phys_addr;
+ size_t size;
+
+ phys_addr = rman_get_start(res);
+ size = rman_get_size(res);
+
+ vm_phys_fictitious_unreg_range(phys_addr, phys_addr + size);
+ return (bus_release_resource(child, SYS_RES_MEMORY, res_id, res));
+}
+
static device_method_t xenpv_methods[] = {
/* Device interface */
DEVMETHOD(device_identify, xenpv_identify),
@@ -100,6 +158,10 @@ static device_method_t xenpv_methods[] = {
DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ /* Interface to allocate memory for foreign mappings */
+ DEVMETHOD(xenmem_alloc, xenpv_alloc_physmem),
+ DEVMETHOD(xenmem_free, xenpv_free_physmem),
+
DEVMETHOD_END
};
@@ -110,3 +172,25 @@ static driver_t xenpv_driver = {
};
DRIVER_MODULE(xenpv, nexus, xenpv_driver, xenpv_devclass, 0, 0);
+
+struct resource *
+xenmem_alloc(device_t dev, int *res_id, size_t size)
+{
+ device_t parent;
+
+ parent = device_get_parent(dev);
+ if (parent == NULL)
+ return (NULL);
+ return (XENMEM_ALLOC(parent, dev, res_id, size));
+}
+
+int
+xenmem_free(device_t dev, int res_id, struct resource *res)
+{
+ device_t parent;
+
+ parent = device_get_parent(dev);
+ if (parent == NULL)
+ return (ENXIO);
+ return (XENMEM_FREE(parent, dev, res_id, res));
+}
diff --git a/sys/xen/xen-os.h b/sys/xen/xen-os.h
index c982d55..7ceef4f 100644
--- a/sys/xen/xen-os.h
+++ b/sys/xen/xen-os.h
@@ -89,6 +89,13 @@ xen_initial_domain(void)
(HYPERVISOR_start_info->flags & SIF_INITDOMAIN) != 0);
}
+/*
+ * Functions to allocate/free unused memory in order
+ * to map memory from other domains.
+ */
+struct resource *xenmem_alloc(device_t dev, int *res_id, size_t size);
+int xenmem_free(device_t dev, int res_id, struct resource *res);
+
/* Debug/emergency function, prints directly to hypervisor console */
void xc_printf(const char *, ...) __printflike(1, 2);
diff --git a/sys/xen/xenmem/xenmem_if.m b/sys/xen/xenmem/xenmem_if.m
new file mode 100644
index 0000000..5cc2171
--- /dev/null
+++ b/sys/xen/xenmem/xenmem_if.m
@@ -0,0 +1,95 @@
+#-
+# Copyright (c) 2015 Roger Pau Monné <royger@FreeBSD.org>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+#
+
+#include <sys/bus.h>
+
+INTERFACE xenmem;
+
+#
+# Default implementations of some methods.
+#
+CODE {
+ static struct resource *
+ xenmem_generic_alloc(device_t dev, device_t child, int *res_id,
+ size_t size)
+ {
+ device_t parent;
+
+ parent = device_get_parent(dev);
+ if (parent == NULL)
+ return (NULL);
+ return (XENMEM_ALLOC(parent, child, res_id, size));
+ }
+
+ static int
+ xenmem_generic_free(device_t dev, device_t child, int res_id,
+ struct resource *res)
+ {
+ device_t parent;
+
+ parent = device_get_parent(dev);
+ if (parent == NULL)
+ return (ENXIO);
+ return (XENMEM_FREE(parent, child, res_id, res));
+ }
+};
+
+/**
+ * @brief Request for unused physical memory regions.
+ *
+ * @param _dev the device whose child was being probed.
+ * @param _child the child device which failed to probe.
+ * @param _res_id a pointer to the resource identifier.
+ * @param _size size of the required memory region.
+ *
+ * @returns the resource which was allocated or @c NULL if no
+ * resource could be allocated.
+ */
+METHOD struct resource * alloc {
+ device_t _dev;
+ device_t _child;
+ int *_res_id;
+ size_t _size;
+} DEFAULT xenmem_generic_alloc;
+
+/**
+ * @brief Free physical memory regions.
+ *
+ * @param _dev the device whose child was being probed.
+ * @param _child the child device which failed to probe.
+ * @param _res_id the resource identifier.
+ * @param _res the resource.
+ *
+ * @returns 0 on success, otherwise an error code.
+ */
+METHOD int free {
+ device_t _dev;
+ device_t _child;
+ int _res_id;
+ struct resource *_res;
+} DEFAULT xenmem_generic_free;
diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc
index a519580..4a2ba751 100644
--- a/tools/build/mk/OptionalObsoleteFiles.inc
+++ b/tools/build/mk/OptionalObsoleteFiles.inc
@@ -1009,12 +1009,6 @@ OLD_FILES+=usr/bin/c++filt
.endif
OLD_FILES+=usr/bin/g++
OLD_FILES+=usr/libexec/cc1plus
-.if ${MK_GCC} == no
-OLD_FILES+=usr/bin/gperf
-OLD_FILES+=usr/share/info/gperf.info.gz
-OLD_FILES+=usr/share/man/man1/gperf.1.gz
-OLD_FILES+=usr/share/man/man1/gperf.7.gz
-.endif
.endif
.if ${MK_FMTREE} == no
@@ -1729,6 +1723,7 @@ OLD_FILES+=usr/bin/g++
OLD_FILES+=usr/bin/gcc
OLD_FILES+=usr/bin/gcov
OLD_FILES+=usr/bin/gcpp
+OLD_FILES+=usr/bin/gperf
.if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "i386"
OLD_FILES+=usr/include/gcc/4.2/__wmmintrin_aes.h
OLD_FILES+=usr/include/gcc/4.2/__wmmintrin_pclmul.h
@@ -1754,10 +1749,13 @@ OLD_FILES+=usr/share/info/cpp.info.gz
OLD_FILES+=usr/share/info/cppinternals.info.gz
OLD_FILES+=usr/share/info/gcc.info.gz
OLD_FILES+=usr/share/info/gccint.info.gz
+OLD_FILES+=usr/share/info/gperf.info.gz
OLD_FILES+=usr/share/man/man1/g++.1.gz
OLD_FILES+=usr/share/man/man1/gcc.1.gz
OLD_FILES+=usr/share/man/man1/gcov.1.gz
OLD_FILES+=usr/share/man/man1/gcpp.1.gz
+OLD_FILES+=usr/share/man/man1/gperf.1.gz
+OLD_FILES+=usr/share/man/man1/gperf.7.gz
.endif
.if ${MK_GCOV} == no
diff --git a/usr.bin/checknr/checknr.c b/usr.bin/checknr/checknr.c
index 235ec33..06395b0 100644
--- a/usr.bin/checknr/checknr.c
+++ b/usr.bin/checknr/checknr.c
@@ -313,7 +313,7 @@ static void
process(FILE *f)
{
int i, n;
- char mac[512]; /* The current macro or nroff command */
+ char mac[64]; /* The current macro or nroff command */
char *line;
size_t linecap;
int pl;
diff --git a/usr.bin/col/col.c b/usr.bin/col/col.c
index 74c59b6..c620bcb 100644
--- a/usr.bin/col/col.c
+++ b/usr.bin/col/col.c
@@ -96,6 +96,7 @@ struct line_str {
int l_max_col; /* max column in the line */
};
+static void addto_lineno(int *, int);
static LINE *alloc_line(void);
static void dowarn(int);
static void flush_line(LINE *);
@@ -108,7 +109,7 @@ static CSET last_set; /* char_set of last char printed */
static LINE *lines;
static int compress_spaces; /* if doing space -> tab conversion */
static int fine; /* if `fine' resolution (half lines) */
-static int max_bufd_lines; /* max # lines to keep in memory */
+static int max_bufd_lines; /* max # of half lines to keep in memory */
static int nblank_lines; /* # blanks after last flushed line */
static int no_backspaces; /* if not to output any backspaces */
static int pass_unknown_seqs; /* pass unknown control sequences */
@@ -133,6 +134,7 @@ main(int argc, char **argv)
int this_line; /* line l points to */
int nflushd_lines; /* number of lines that were flushed */
int adjust, opt, warned, width;
+ const char *errstr;
cap_rights_t rights;
unsigned long cmd;
@@ -151,7 +153,7 @@ main(int argc, char **argv)
if (cap_enter() < 0 && errno != ENOSYS)
err(1, "unable to enter capability mode");
- max_bufd_lines = 128;
+ max_bufd_lines = 256;
compress_spaces = 1; /* compress spaces into tabs */
while ((opt = getopt(argc, argv, "bfhl:px")) != -1)
switch (opt) {
@@ -165,8 +167,11 @@ main(int argc, char **argv)
compress_spaces = 1;
break;
case 'l': /* buffered line count */
- if ((max_bufd_lines = atoi(optarg)) <= 0)
- errx(1, "bad -l argument %s", optarg);
+ max_bufd_lines = strtonum(optarg, 1,
+ (INT_MAX - BUFFER_MARGIN) / 2, &errstr) * 2;
+ if (errstr != NULL)
+ errx(1, "bad -l argument, %s: %s", errstr,
+ optarg);
break;
case 'p': /* pass unknown control sequences */
pass_unknown_seqs = 1;
@@ -182,9 +187,6 @@ main(int argc, char **argv)
if (optind != argc)
usage();
- /* this value is in half lines */
- max_bufd_lines *= 2;
-
adjust = cur_col = extra_lines = warned = 0;
cur_line = max_line = nflushd_lines = this_line = 0;
cur_set = last_set = CS_NORMAL;
@@ -204,19 +206,19 @@ main(int argc, char **argv)
case ESC: /* just ignore EOF */
switch(getwchar()) {
case RLF:
- cur_line -= 2;
+ addto_lineno(&cur_line, -2);
break;
case RHLF:
- cur_line--;
+ addto_lineno(&cur_line, -1);
break;
case FHLF:
- cur_line++;
+ addto_lineno(&cur_line, 1);
if (cur_line > max_line)
max_line = cur_line;
}
continue;
case NL:
- cur_line += 2;
+ addto_lineno(&cur_line, 2);
if (cur_line > max_line)
max_line = cur_line;
cur_col = 0;
@@ -235,7 +237,7 @@ main(int argc, char **argv)
++cur_col;
continue;
case VT:
- cur_line -= 2;
+ addto_lineno(&cur_line, -2);
continue;
}
if (iswspace(ch)) {
@@ -248,58 +250,61 @@ main(int argc, char **argv)
}
/* Must stuff ch in a line - are we at the right one? */
- if (cur_line != this_line - adjust) {
+ if (cur_line + adjust != this_line) {
LINE *lnew;
- int nmove;
-
- adjust = 0;
- nmove = cur_line - this_line;
- if (!fine) {
- /* round up to next line */
- if (cur_line & 1) {
- adjust = 1;
- nmove++;
- }
- }
- if (nmove < 0) {
- for (; nmove < 0 && l->l_prev; nmove++)
+
+ /* round up to next line */
+ adjust = !fine && (cur_line & 1);
+
+ if (cur_line + adjust < this_line) {
+ while (cur_line + adjust < this_line &&
+ l->l_prev != NULL) {
l = l->l_prev;
- if (nmove) {
+ this_line--;
+ }
+ if (cur_line + adjust < this_line) {
if (nflushd_lines == 0) {
/*
* Allow backup past first
* line if nothing has been
* flushed yet.
*/
- for (; nmove < 0; nmove++) {
+ while (cur_line + adjust
+ < this_line) {
lnew = alloc_line();
l->l_prev = lnew;
lnew->l_next = l;
l = lines = lnew;
extra_lines++;
+ this_line--;
}
} else {
if (!warned++)
dowarn(cur_line);
- cur_line -= nmove;
+ cur_line = this_line - adjust;
}
}
} else {
/* may need to allocate here */
- for (; nmove > 0 && l->l_next; nmove--)
+ while (cur_line + adjust > this_line) {
+ if (l->l_next == NULL) {
+ l->l_next = alloc_line();
+ l->l_next->l_prev = l;
+ }
l = l->l_next;
- for (; nmove > 0; nmove--) {
- lnew = alloc_line();
- lnew->l_prev = l;
- l->l_next = lnew;
- l = lnew;
+ this_line++;
}
}
- this_line = cur_line + adjust;
- nmove = this_line - nflushd_lines;
- if (nmove >= max_bufd_lines + BUFFER_MARGIN) {
- nflushd_lines += nmove - max_bufd_lines;
- flush_lines(nmove - max_bufd_lines);
+ if (this_line > nflushd_lines &&
+ this_line - nflushd_lines >=
+ max_bufd_lines + BUFFER_MARGIN) {
+ if (extra_lines) {
+ flush_lines(extra_lines);
+ extra_lines = 0;
+ }
+ flush_lines(this_line - nflushd_lines -
+ max_bufd_lines);
+ nflushd_lines = this_line - max_bufd_lines;
}
}
/* grow line's buffer? */
@@ -330,25 +335,23 @@ main(int argc, char **argv)
}
if (ferror(stdin))
err(1, NULL);
- if (max_line == 0)
- exit(0); /* no lines, so just exit */
+ if (extra_lines)
+ flush_lines(extra_lines);
/* goto the last line that had a character on it */
for (; l->l_next; l = l->l_next)
this_line++;
- flush_lines(this_line - nflushd_lines + extra_lines + 1);
+ flush_lines(this_line - nflushd_lines + 1);
/* make sure we leave things in a sane state */
if (last_set != CS_NORMAL)
PUTC(SI);
/* flush out the last few blank lines */
- nblank_lines = max_line - this_line;
+ if (max_line > this_line)
+ nblank_lines = max_line - this_line;
if (max_line & 1)
nblank_lines++;
- else if (!nblank_lines)
- /* missing a \n on the last line? */
- nblank_lines = 2;
flush_blanks();
exit(0);
}
@@ -365,7 +368,8 @@ flush_lines(int nflush)
flush_blanks();
flush_line(l);
}
- nblank_lines++;
+ if (l->l_line || l->l_next)
+ nblank_lines++;
if (l->l_line)
(void)free(l->l_line);
free_line(l);
@@ -517,6 +521,23 @@ flush_line(LINE *l)
}
}
+/*
+ * Increment or decrement a line number, checking for overflow.
+ * Stop one below INT_MAX such that the adjust variable is safe.
+ */
+void
+addto_lineno(int *lno, int offset)
+{
+ if (offset > 0) {
+ if (*lno >= INT_MAX - offset)
+ errx(1, "too many lines");
+ } else {
+ if (*lno < INT_MIN - offset)
+ errx(1, "too many reverse line feeds");
+ }
+ *lno += offset;
+}
+
#define NALLOC 64
static LINE *line_freelist;
diff --git a/usr.bin/netstat/if.c b/usr.bin/netstat/if.c
index f04c531..109ef2d 100644
--- a/usr.bin/netstat/if.c
+++ b/usr.bin/netstat/if.c
@@ -315,7 +315,7 @@ intpr(int interval, void (*pfunc)(char *), int af)
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
bool network = false, link = false;
- char *name;
+ char *name, *xname, buf[IFNAMSIZ+1];
if (interface != NULL && strcmp(ifa->ifa_name, interface) != 0)
continue;
@@ -341,10 +341,20 @@ intpr(int interval, void (*pfunc)(char *), int af)
xo_open_instance("interface");
+ if ((ifa->ifa_flags & IFF_UP) == 0) {
+ xname = stpcpy(buf, name);
+ *xname++ = '*';
+ *xname = '\0';
+ xname = buf;
+ } else
+ xname = name;
+
if (Wflag)
- xo_emit("{tk:name/%-7.7s}", name);
+ xo_emit("{etk:name/%s}{e:flags/0x%x}{d:/%7.7s}",
+ name, ifa->ifa_flags, xname);
else
- xo_emit("{tk:name/%-5.5s}", name);
+ xo_emit("{etk:name/%s}{e:flags/0x%x}{d:/%5.5s}",
+ name, ifa->ifa_flags, xname);
#define IFA_MTU(ifa) (((struct if_data *)(ifa)->ifa_data)->ifi_mtu)
show_stat("lu", 6, "mtu", IFA_MTU(ifa), IFA_MTU(ifa));
diff --git a/usr.sbin/bhyve/inout.c b/usr.sbin/bhyve/inout.c
index 402b953..929bb3c 100644
--- a/usr.sbin/bhyve/inout.c
+++ b/usr.sbin/bhyve/inout.c
@@ -107,7 +107,7 @@ emulate_inout(struct vmctx *ctx, int vcpu, struct vm_exit *vmexit, int strict)
uint32_t eax, val;
inout_func_t handler;
void *arg;
- int error, retval;
+ int error, fault, retval;
enum vm_reg_name idxreg;
uint64_t gla, index, iterations, count;
struct vm_inout_str *vis;
@@ -163,11 +163,11 @@ emulate_inout(struct vmctx *ctx, int vcpu, struct vm_exit *vmexit, int strict)
}
error = vm_copy_setup(ctx, vcpu, &vis->paging, gla,
- bytes, prot, iov, nitems(iov));
- if (error == -1) {
+ bytes, prot, iov, nitems(iov), &fault);
+ if (error) {
retval = -1; /* Unrecoverable error */
break;
- } else if (error == 1) {
+ } else if (fault) {
retval = 0; /* Resume guest to handle fault */
break;
}
diff --git a/usr.sbin/bhyve/pci_ahci.c b/usr.sbin/bhyve/pci_ahci.c
index 31e02f8..35a0859 100644
--- a/usr.sbin/bhyve/pci_ahci.c
+++ b/usr.sbin/bhyve/pci_ahci.c
@@ -2093,7 +2093,7 @@ pci_ahci_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
struct pci_ahci_softc *sc = pi->pi_arg;
assert(baridx == 5);
- assert(size == 4);
+ assert((offset % 4) == 0 && size == 4);
pthread_mutex_lock(&sc->mtx);
@@ -2182,24 +2182,29 @@ pci_ahci_port_read(struct pci_ahci_softc *sc, uint64_t offset)
static uint64_t
pci_ahci_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx,
- uint64_t offset, int size)
+ uint64_t regoff, int size)
{
struct pci_ahci_softc *sc = pi->pi_arg;
+ uint64_t offset;
uint32_t value;
assert(baridx == 5);
- assert(size == 4);
+ assert(size == 1 || size == 2 || size == 4);
+ assert((regoff & (size - 1)) == 0);
pthread_mutex_lock(&sc->mtx);
+ offset = regoff & ~0x3; /* round down to a multiple of 4 bytes */
if (offset < AHCI_OFFSET)
value = pci_ahci_host_read(sc, offset);
else if (offset < AHCI_OFFSET + sc->ports * AHCI_STEP)
value = pci_ahci_port_read(sc, offset);
else {
value = 0;
- WPRINTF("pci_ahci: unknown i/o read offset 0x%"PRIx64"\n", offset);
+ WPRINTF("pci_ahci: unknown i/o read offset 0x%"PRIx64"\n",
+ regoff);
}
+ value >>= 8 * (regoff & 0x3);
pthread_mutex_unlock(&sc->mtx);
diff --git a/usr.sbin/bhyve/pci_virtio_net.c b/usr.sbin/bhyve/pci_virtio_net.c
index 7227488..1a029d5 100644
--- a/usr.sbin/bhyve/pci_virtio_net.c
+++ b/usr.sbin/bhyve/pci_virtio_net.c
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include <sys/select.h>
#include <sys/uio.h>
#include <sys/ioctl.h>
+#include <machine/atomic.h>
#include <net/ethernet.h>
#include <errno.h>
@@ -453,7 +454,7 @@ pci_vtnet_tx_thread(void *param)
{
struct pci_vtnet_softc *sc = param;
struct vqueue_info *vq;
- int have_work, error;
+ int error;
vq = &sc->vsc_queues[VTNET_TXQ];
@@ -467,20 +468,16 @@ pci_vtnet_tx_thread(void *param)
for (;;) {
/* note - tx mutex is locked here */
- do {
+ while (sc->resetting || !vq_has_descs(vq)) {
vq->vq_used->vu_flags &= ~VRING_USED_F_NO_NOTIFY;
- if (sc->resetting)
- have_work = 0;
- else
- have_work = vq_has_descs(vq);
-
- if (!have_work) {
- sc->tx_in_progress = 0;
- error = pthread_cond_wait(&sc->tx_cond,
- &sc->tx_mtx);
- assert(error == 0);
- }
- } while (!have_work);
+ mb();
+ if (!sc->resetting && vq_has_descs(vq))
+ break;
+
+ sc->tx_in_progress = 0;
+ error = pthread_cond_wait(&sc->tx_cond, &sc->tx_mtx);
+ assert(error == 0);
+ }
vq->vq_used->vu_flags |= VRING_USED_F_NO_NOTIFY;
sc->tx_in_progress = 1;
pthread_mutex_unlock(&sc->tx_mtx);
diff --git a/usr.sbin/bhyve/task_switch.c b/usr.sbin/bhyve/task_switch.c
index ba6a9d2..69dfaae 100644
--- a/usr.sbin/bhyve/task_switch.c
+++ b/usr.sbin/bhyve/task_switch.c
@@ -202,7 +202,8 @@ desc_table_limit_check(struct vmctx *ctx, int vcpu, uint16_t sel)
*/
static int
desc_table_rw(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging,
- uint16_t sel, struct user_segment_descriptor *desc, bool doread)
+ uint16_t sel, struct user_segment_descriptor *desc, bool doread,
+ int *faultptr)
{
struct iovec iov[2];
uint64_t base;
@@ -215,28 +216,30 @@ desc_table_rw(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging,
assert(limit >= SEL_LIMIT(sel));
error = vm_copy_setup(ctx, vcpu, paging, base + SEL_START(sel),
- sizeof(*desc), doread ? PROT_READ : PROT_WRITE, iov, nitems(iov));
- if (error == 0) {
- if (doread)
- vm_copyin(ctx, vcpu, iov, desc, sizeof(*desc));
- else
- vm_copyout(ctx, vcpu, desc, iov, sizeof(*desc));
- }
- return (error);
+ sizeof(*desc), doread ? PROT_READ : PROT_WRITE, iov, nitems(iov),
+ faultptr);
+ if (error || *faultptr)
+ return (error);
+
+ if (doread)
+ vm_copyin(ctx, vcpu, iov, desc, sizeof(*desc));
+ else
+ vm_copyout(ctx, vcpu, desc, iov, sizeof(*desc));
+ return (0);
}
static int
desc_table_read(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging,
- uint16_t sel, struct user_segment_descriptor *desc)
+ uint16_t sel, struct user_segment_descriptor *desc, int *faultptr)
{
- return (desc_table_rw(ctx, vcpu, paging, sel, desc, true));
+ return (desc_table_rw(ctx, vcpu, paging, sel, desc, true, faultptr));
}
static int
desc_table_write(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging,
- uint16_t sel, struct user_segment_descriptor *desc)
+ uint16_t sel, struct user_segment_descriptor *desc, int *faultptr)
{
- return (desc_table_rw(ctx, vcpu, paging, sel, desc, false));
+ return (desc_table_rw(ctx, vcpu, paging, sel, desc, false, faultptr));
}
/*
@@ -248,7 +251,7 @@ desc_table_write(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging,
*/
static int
read_tss_descriptor(struct vmctx *ctx, int vcpu, struct vm_task_switch *ts,
- uint16_t sel, struct user_segment_descriptor *desc)
+ uint16_t sel, struct user_segment_descriptor *desc, int *faultptr)
{
struct vm_guest_paging sup_paging;
int error;
@@ -267,7 +270,7 @@ read_tss_descriptor(struct vmctx *ctx, int vcpu, struct vm_task_switch *ts,
sup_paging = ts->paging;
sup_paging.cpl = 0; /* implicit supervisor mode */
- error = desc_table_read(ctx, vcpu, &sup_paging, sel, desc);
+ error = desc_table_read(ctx, vcpu, &sup_paging, sel, desc, faultptr);
return (error);
}
@@ -301,14 +304,10 @@ ldt_desc(int sd_type)
/*
* Validate the descriptor 'seg_desc' associated with 'segment'.
- *
- * Returns 0 on success.
- * Returns 1 if an exception was injected into the guest.
- * Returns -1 otherwise.
*/
static int
validate_seg_desc(struct vmctx *ctx, int vcpu, struct vm_task_switch *ts,
- int segment, struct seg_desc *seg_desc)
+ int segment, struct seg_desc *seg_desc, int *faultptr)
{
struct vm_guest_paging sup_paging;
struct user_segment_descriptor usd;
@@ -369,8 +368,8 @@ validate_seg_desc(struct vmctx *ctx, int vcpu, struct vm_task_switch *ts,
/* Read the descriptor from the GDT/LDT */
sup_paging = ts->paging;
sup_paging.cpl = 0; /* implicit supervisor mode */
- error = desc_table_read(ctx, vcpu, &sup_paging, sel, &usd);
- if (error)
+ error = desc_table_read(ctx, vcpu, &sup_paging, sel, &usd, faultptr);
+ if (error || *faultptr)
return (error);
/* Verify that the descriptor type is compatible with the segment */
@@ -476,14 +475,10 @@ update_seg_desc(struct vmctx *ctx, int vcpu, int reg, struct seg_desc *sd)
/*
* Update the vcpu registers to reflect the state of the new task.
- *
- * Returns 0 on success.
- * Returns 1 if an exception was injected into the guest.
- * Returns -1 otherwise.
*/
static int
tss32_restore(struct vmctx *ctx, int vcpu, struct vm_task_switch *ts,
- uint16_t ot_sel, struct tss32 *tss, struct iovec *iov)
+ uint16_t ot_sel, struct tss32 *tss, struct iovec *iov, int *faultptr)
{
struct seg_desc seg_desc, seg_desc2;
uint64_t *pdpte, maxphyaddr, reserved;
@@ -565,8 +560,9 @@ tss32_restore(struct vmctx *ctx, int vcpu, struct vm_task_switch *ts,
vm_copyout(ctx, vcpu, tss, iov, sizeof(*tss));
/* Validate segment descriptors */
- error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_LDTR, &seg_desc);
- if (error)
+ error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_LDTR, &seg_desc,
+ faultptr);
+ if (error || *faultptr)
return (error);
update_seg_desc(ctx, vcpu, VM_REG_GUEST_LDTR, &seg_desc);
@@ -579,33 +575,40 @@ tss32_restore(struct vmctx *ctx, int vcpu, struct vm_task_switch *ts,
* VM-entry checks so the guest can handle any exception injected
* during task switch emulation.
*/
- error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_CS, &seg_desc);
- if (error)
+ error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_CS, &seg_desc,
+ faultptr);
+ if (error || *faultptr)
return (error);
- error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_SS, &seg_desc2);
- if (error)
+
+ error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_SS, &seg_desc2,
+ faultptr);
+ if (error || *faultptr)
return (error);
update_seg_desc(ctx, vcpu, VM_REG_GUEST_CS, &seg_desc);
update_seg_desc(ctx, vcpu, VM_REG_GUEST_SS, &seg_desc2);
ts->paging.cpl = tss->tss_cs & SEL_RPL_MASK;
- error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_DS, &seg_desc);
- if (error)
+ error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_DS, &seg_desc,
+ faultptr);
+ if (error || *faultptr)
return (error);
update_seg_desc(ctx, vcpu, VM_REG_GUEST_DS, &seg_desc);
- error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_ES, &seg_desc);
- if (error)
+ error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_ES, &seg_desc,
+ faultptr);
+ if (error || *faultptr)
return (error);
update_seg_desc(ctx, vcpu, VM_REG_GUEST_ES, &seg_desc);
- error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_FS, &seg_desc);
- if (error)
+ error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_FS, &seg_desc,
+ faultptr);
+ if (error || *faultptr)
return (error);
update_seg_desc(ctx, vcpu, VM_REG_GUEST_FS, &seg_desc);
- error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_GS, &seg_desc);
- if (error)
+ error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_GS, &seg_desc,
+ faultptr);
+ if (error || *faultptr)
return (error);
update_seg_desc(ctx, vcpu, VM_REG_GUEST_GS, &seg_desc);
@@ -616,14 +619,10 @@ tss32_restore(struct vmctx *ctx, int vcpu, struct vm_task_switch *ts,
* Push an error code on the stack of the new task. This is needed if the
* task switch was triggered by a hardware exception that causes an error
* code to be saved (e.g. #PF).
- *
- * Returns 0 on success.
- * Returns 1 if an exception was injected into the guest.
- * Returns -1 otherwise.
*/
static int
push_errcode(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging,
- int task_type, uint32_t errcode)
+ int task_type, uint32_t errcode, int *faultptr)
{
struct iovec iov[2];
struct seg_desc seg_desc;
@@ -632,6 +631,8 @@ push_errcode(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging,
uint32_t esp;
uint16_t stacksel;
+ *faultptr = 0;
+
cr0 = GETREG(ctx, vcpu, VM_REG_GUEST_CR0);
rflags = GETREG(ctx, vcpu, VM_REG_GUEST_RFLAGS);
stacksel = GETREG(ctx, vcpu, VM_REG_GUEST_SS);
@@ -666,17 +667,19 @@ push_errcode(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging,
if (vie_calculate_gla(paging->cpu_mode, VM_REG_GUEST_SS,
&seg_desc, esp, bytes, stacksize, PROT_WRITE, &gla)) {
sel_exception(ctx, vcpu, IDT_SS, stacksel, 1);
- return (1);
+ *faultptr = 1;
+ return (0);
}
if (vie_alignment_check(paging->cpl, bytes, cr0, rflags, gla)) {
vm_inject_ac(ctx, vcpu, 1);
- return (1);
+ *faultptr = 1;
+ return (0);
}
error = vm_copy_setup(ctx, vcpu, paging, gla, bytes, PROT_WRITE,
- iov, nitems(iov));
- if (error)
+ iov, nitems(iov), faultptr);
+ if (error || *faultptr)
return (error);
vm_copyout(ctx, vcpu, &errcode, iov, bytes);
@@ -687,16 +690,13 @@ push_errcode(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging,
/*
* Evaluate return value from helper functions and potentially return to
* the VM run loop.
- * 0: success
- * +1: an exception was injected into the guest vcpu
- * -1: unrecoverable/programming error
*/
-#define CHKERR(x) \
+#define CHKERR(error,fault) \
do { \
- assert(((x) == 0) || ((x) == 1) || ((x) == -1)); \
- if ((x) == -1) \
+ assert((error == 0) || (error == EFAULT)); \
+ if (error) \
return (VMEXIT_ABORT); \
- else if ((x) == 1) \
+ else if (fault) \
return (VMEXIT_CONTINUE); \
} while (0)
@@ -711,7 +711,7 @@ vmexit_task_switch(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu)
struct iovec nt_iov[2], ot_iov[2];
uint64_t cr0, ot_base;
uint32_t eip, ot_lim, access;
- int error, ext, minlimit, nt_type, ot_type, vcpu;
+ int error, ext, fault, minlimit, nt_type, ot_type, vcpu;
enum task_switch_reason reason;
uint16_t nt_sel, ot_sel;
@@ -739,8 +739,9 @@ vmexit_task_switch(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu)
sup_paging.cpl = 0; /* implicit supervisor mode */
/* Fetch the new TSS descriptor */
- error = read_tss_descriptor(ctx, vcpu, task_switch, nt_sel, &nt_desc);
- CHKERR(error);
+ error = read_tss_descriptor(ctx, vcpu, task_switch, nt_sel, &nt_desc,
+ &fault);
+ CHKERR(error, fault);
nt = usd_to_seg_desc(&nt_desc);
@@ -792,8 +793,8 @@ vmexit_task_switch(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu)
/* Fetch the new TSS */
error = vm_copy_setup(ctx, vcpu, &sup_paging, nt.base, minlimit + 1,
- PROT_READ | PROT_WRITE, nt_iov, nitems(nt_iov));
- CHKERR(error);
+ PROT_READ | PROT_WRITE, nt_iov, nitems(nt_iov), &fault);
+ CHKERR(error, fault);
vm_copyin(ctx, vcpu, nt_iov, &newtss, minlimit + 1);
/* Get the old TSS selector from the guest's task register */
@@ -818,13 +819,14 @@ vmexit_task_switch(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu)
assert(ot_type == SDT_SYS386BSY || ot_type == SDT_SYS286BSY);
/* Fetch the old TSS descriptor */
- error = read_tss_descriptor(ctx, vcpu, task_switch, ot_sel, &ot_desc);
- CHKERR(error);
+ error = read_tss_descriptor(ctx, vcpu, task_switch, ot_sel, &ot_desc,
+ &fault);
+ CHKERR(error, fault);
/* Get the old TSS */
error = vm_copy_setup(ctx, vcpu, &sup_paging, ot_base, minlimit + 1,
- PROT_READ | PROT_WRITE, ot_iov, nitems(ot_iov));
- CHKERR(error);
+ PROT_READ | PROT_WRITE, ot_iov, nitems(ot_iov), &fault);
+ CHKERR(error, fault);
vm_copyin(ctx, vcpu, ot_iov, &oldtss, minlimit + 1);
/*
@@ -834,8 +836,8 @@ vmexit_task_switch(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu)
if (reason == TSR_IRET || reason == TSR_JMP) {
ot_desc.sd_type &= ~0x2;
error = desc_table_write(ctx, vcpu, &sup_paging, ot_sel,
- &ot_desc);
- CHKERR(error);
+ &ot_desc, &fault);
+ CHKERR(error, fault);
}
if (nt_type == SDT_SYS286BSY || nt_type == SDT_SYS286TSS) {
@@ -853,8 +855,8 @@ vmexit_task_switch(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu)
if (reason != TSR_IRET) {
nt_desc.sd_type |= 0x2;
error = desc_table_write(ctx, vcpu, &sup_paging, nt_sel,
- &nt_desc);
- CHKERR(error);
+ &nt_desc, &fault);
+ CHKERR(error, fault);
}
/* Update task register to point at the new TSS */
@@ -877,8 +879,9 @@ vmexit_task_switch(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu)
assert(error == 0);
/* Load processor state from new TSS */
- error = tss32_restore(ctx, vcpu, task_switch, ot_sel, &newtss, nt_iov);
- CHKERR(error);
+ error = tss32_restore(ctx, vcpu, task_switch, ot_sel, &newtss, nt_iov,
+ &fault);
+ CHKERR(error, fault);
/*
* Section "Interrupt Tasks" in Intel SDM, Vol 3: if an exception
@@ -889,8 +892,8 @@ vmexit_task_switch(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu)
assert(task_switch->ext);
assert(task_switch->reason == TSR_IDT_GATE);
error = push_errcode(ctx, vcpu, &task_switch->paging, nt_type,
- task_switch->errcode);
- CHKERR(error);
+ task_switch->errcode, &fault);
+ CHKERR(error, fault);
}
/*
diff --git a/usr.sbin/pmcstat/pmcstat.8 b/usr.sbin/pmcstat/pmcstat.8
index 9a204a4..6478241 100644
--- a/usr.sbin/pmcstat/pmcstat.8
+++ b/usr.sbin/pmcstat/pmcstat.8
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd March 27, 2015
+.Dd May 8, 2015
.Dt PMCSTAT 8
.Os
.Sh NAME
@@ -279,8 +279,9 @@ Set the pathname of the kernel directory to argument
This directory specifies where
.Nm
should look for the kernel and its modules.
-The default is
-.Pa /boot/kernel .
+The default is to use the path of the running kernel obtained from the
+.Va kern.bootfile
+sysctl.
.It Fl l Ar secs
Set system-wide performance measurement duration for
.Ar secs
diff --git a/usr.sbin/pmcstat/pmcstat.c b/usr.sbin/pmcstat/pmcstat.c
index 77613b4..c7f36bc 100644
--- a/usr.sbin/pmcstat/pmcstat.c
+++ b/usr.sbin/pmcstat/pmcstat.c
@@ -557,7 +557,7 @@ main(int argc, char **argv)
int c, check_driver_stats, current_sampling_count;
int do_callchain, do_descendants, do_logproccsw, do_logprocexit;
int do_print, do_read;
- size_t dummy;
+ size_t len;
int graphdepth;
int pipefd[2], rfd;
int use_cumulative_counts;
@@ -586,7 +586,6 @@ main(int argc, char **argv)
args.pa_verbosity = 1;
args.pa_logfd = -1;
args.pa_fsroot = "";
- args.pa_kernel = strdup("/boot/kernel");
args.pa_samplesdir = ".";
args.pa_printfile = stderr;
args.pa_graphdepth = DEFAULT_CALLGRAPH_DEPTH;
@@ -610,12 +609,20 @@ main(int argc, char **argv)
ev = NULL;
CPU_ZERO(&cpumask);
+ /* Default to using the running system kernel. */
+ len = 0;
+ if (sysctlbyname("kern.bootfile", NULL, &len, NULL, 0) == -1)
+ err(EX_OSERR, "ERROR: Cannot determine path of running kernel");
+ args.pa_kernel = malloc(len + 1);
+ if (sysctlbyname("kern.bootfile", args.pa_kernel, &len, NULL, 0) == -1)
+ err(EX_OSERR, "ERROR: Cannot determine path of running kernel");
+
/*
* The initial CPU mask specifies all non-halted CPUS in the
* system.
*/
- dummy = sizeof(int);
- if (sysctlbyname("hw.ncpu", &ncpu, &dummy, NULL, 0) < 0)
+ len = sizeof(int);
+ if (sysctlbyname("hw.ncpu", &ncpu, &len, NULL, 0) < 0)
err(EX_OSERR, "ERROR: Cannot determine the number of CPUs");
for (hcpu = 0; hcpu < ncpu; hcpu++)
CPU_SET(hcpu, &cpumask);
@@ -1061,33 +1068,31 @@ main(int argc, char **argv)
);
/*
- * Check if "-k kerneldir" was specified, and if whether
- * 'kerneldir' actually refers to a file. If so, use
- * `dirname path` to determine the kernel directory.
+ * Check if 'kerneldir' refers to a file rather than a
+ * directory. If so, use `dirname path` to determine the
+ * kernel directory.
*/
- if (args.pa_flags & FLAG_HAS_KERNELPATH) {
- (void) snprintf(buffer, sizeof(buffer), "%s%s", args.pa_fsroot,
- args.pa_kernel);
+ (void) snprintf(buffer, sizeof(buffer), "%s%s", args.pa_fsroot,
+ args.pa_kernel);
+ if (stat(buffer, &sb) < 0)
+ err(EX_OSERR, "ERROR: Cannot locate kernel \"%s\"",
+ buffer);
+ if (!S_ISREG(sb.st_mode) && !S_ISDIR(sb.st_mode))
+ errx(EX_USAGE, "ERROR: \"%s\": Unsupported file type.",
+ buffer);
+ if (!S_ISDIR(sb.st_mode)) {
+ tmp = args.pa_kernel;
+ args.pa_kernel = strdup(dirname(args.pa_kernel));
+ free(tmp);
+ (void) snprintf(buffer, sizeof(buffer), "%s%s",
+ args.pa_fsroot, args.pa_kernel);
if (stat(buffer, &sb) < 0)
- err(EX_OSERR, "ERROR: Cannot locate kernel \"%s\"",
+ err(EX_OSERR, "ERROR: Cannot stat \"%s\"",
buffer);
- if (!S_ISREG(sb.st_mode) && !S_ISDIR(sb.st_mode))
- errx(EX_USAGE, "ERROR: \"%s\": Unsupported file type.",
+ if (!S_ISDIR(sb.st_mode))
+ errx(EX_USAGE,
+ "ERROR: \"%s\" is not a directory.",
buffer);
- if (!S_ISDIR(sb.st_mode)) {
- tmp = args.pa_kernel;
- args.pa_kernel = strdup(dirname(args.pa_kernel));
- free(tmp);
- (void) snprintf(buffer, sizeof(buffer), "%s%s",
- args.pa_fsroot, args.pa_kernel);
- if (stat(buffer, &sb) < 0)
- err(EX_OSERR, "ERROR: Cannot stat \"%s\"",
- buffer);
- if (!S_ISDIR(sb.st_mode))
- errx(EX_USAGE,
- "ERROR: \"%s\" is not a directory.",
- buffer);
- }
}
/*
diff --git a/usr.sbin/pmcstat/pmcstat_log.c b/usr.sbin/pmcstat/pmcstat_log.c
index 40de320..8190b28 100644
--- a/usr.sbin/pmcstat/pmcstat_log.c
+++ b/usr.sbin/pmcstat/pmcstat_log.c
@@ -1531,7 +1531,9 @@ pmcstat_analyze_log(void)
free(ppm);
}
- /* associate this process image */
+ /*
+ * Associate this process image.
+ */
image_path = pmcstat_string_intern(
ev.pl_u.pl_x.pl_pathname);
assert(image_path != NULL);
diff --git a/usr.sbin/pw/Makefile b/usr.sbin/pw/Makefile
index 269b145..69953da 100644
--- a/usr.sbin/pw/Makefile
+++ b/usr.sbin/pw/Makefile
@@ -8,7 +8,7 @@ SRCS= pw.c pw_conf.c pw_user.c pw_group.c pw_log.c pw_nis.c pw_vpw.c \
WARNS?= 2
-LIBADD= crypt util
+LIBADD= crypt util sbuf
.include <src.opts.mk>
diff --git a/usr.sbin/pw/fileupd.c b/usr.sbin/pw/fileupd.c
index 7df4bb1..dc32712 100644
--- a/usr.sbin/pw/fileupd.c
+++ b/usr.sbin/pw/fileupd.c
@@ -29,32 +29,11 @@ static const char rcsid[] =
"$FreeBSD$";
#endif /* not lint */
-#include <stdio.h>
-#include <fcntl.h>
#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/param.h>
-#include <errno.h>
-#include <unistd.h>
#include "pwupd.h"
int
-extendline(char **buf, int * buflen, int needed)
-{
- if (needed > *buflen) {
- char *tmp = realloc(*buf, needed);
- if (tmp == NULL)
- return -1;
- *buf = tmp;
- *buflen = needed;
- }
- return *buflen;
-}
-
-int
extendarray(char ***buf, int * buflen, int needed)
{
if (needed > *buflen) {
diff --git a/usr.sbin/pw/grupd.c b/usr.sbin/pw/grupd.c
index 3f78e95..74cc390 100644
--- a/usr.sbin/pw/grupd.c
+++ b/usr.sbin/pw/grupd.c
@@ -35,10 +35,6 @@ static const char rcsid[] =
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <sys/types.h>
-#include <sys/stat.h>
#include <sys/param.h>
#include "pwupd.h"
diff --git a/usr.sbin/pw/pw_conf.c b/usr.sbin/pw/pw_conf.c
index 1289b3e..9dce918 100644
--- a/usr.sbin/pw/pw_conf.c
+++ b/usr.sbin/pw/pw_conf.c
@@ -29,6 +29,8 @@ static const char rcsid[] =
"$FreeBSD$";
#endif /* not lint */
+#include <sys/types.h>
+#include <sys/sbuf.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
@@ -366,6 +368,7 @@ int
write_userconfig(char const * file)
{
int fd;
+ struct sbuf *buf;
if (file == NULL)
file = _PATH_PW_CONF;
@@ -376,126 +379,121 @@ write_userconfig(char const * file)
if ((fp = fdopen(fd, "w")) == NULL)
close(fd);
else {
- int i, j, k;
- int len = LNBUFSZ;
- char *buf = malloc(len);
-
+ int i, j;
+
+ buf = sbuf_new_auto();
for (i = _UC_NONE; i < _UC_FIELDS; i++) {
int quote = 1;
- char const *val = buf;
- *buf = '\0';
+ sbuf_clear(buf);
switch (i) {
case _UC_DEFAULTPWD:
- val = boolean_str(config.default_password);
+ sbuf_cat(buf, boolean_str(config.default_password));
break;
case _UC_REUSEUID:
- val = boolean_str(config.reuse_uids);
+ sbuf_cat(buf, boolean_str(config.reuse_uids));
break;
case _UC_REUSEGID:
- val = boolean_str(config.reuse_gids);
+ sbuf_cat(buf, boolean_str(config.reuse_gids));
break;
case _UC_NISPASSWD:
- val = config.nispasswd ? config.nispasswd : "";
+ sbuf_cat(buf, config.nispasswd ?
+ config.nispasswd : "");
quote = 0;
break;
case _UC_DOTDIR:
- val = config.dotdir ? config.dotdir : boolean_str(0);
+ sbuf_cat(buf, config.dotdir ?
+ config.dotdir : boolean_str(0));
break;
case _UC_NEWMAIL:
- val = config.newmail ? config.newmail : boolean_str(0);
+ sbuf_cat(buf, config.newmail ?
+ config.newmail : boolean_str(0));
break;
case _UC_LOGFILE:
- val = config.logfile ? config.logfile : boolean_str(0);
+ sbuf_cat(buf, config.logfile ?
+ config.logfile : boolean_str(0));
break;
case _UC_HOMEROOT:
- val = config.home;
+ sbuf_cat(buf, config.home);
break;
case _UC_HOMEMODE:
- sprintf(buf, "%04o", config.homemode);
+ sbuf_printf(buf, "%04o", config.homemode);
quote = 0;
break;
case _UC_SHELLPATH:
- val = config.shelldir;
+ sbuf_cat(buf, config.shelldir);
break;
case _UC_SHELLS:
- for (j = k = 0; j < _UC_MAXSHELLS && system_shells[j] != NULL; j++) {
- char lbuf[64];
- int l = snprintf(lbuf, sizeof lbuf, "%s\"%s\"", k ? "," : "", system_shells[j]);
- if (l < 0)
- l = 0;
- if (l + k + 1 < len || extendline(&buf, &len, len + LNBUFSZ) != -1) {
- strcpy(buf + k, lbuf);
- k += l;
- }
+ for (j = 0; j < _UC_MAXSHELLS &&
+ system_shells[j] != NULL; j++) {
+ sbuf_printf(buf, "%s\"%s\"", j ?
+ "," : "", system_shells[j]);
}
quote = 0;
break;
case _UC_DEFAULTSHELL:
- val = config.shell_default ? config.shell_default : bourne_shell;
+ sbuf_cat(buf, config.shell_default ?
+ config.shell_default : bourne_shell);
break;
case _UC_DEFAULTGROUP:
- val = config.default_group ? config.default_group : "";
+ sbuf_cat(buf, config.default_group ?
+ config.default_group : "");
break;
case _UC_EXTRAGROUPS:
extendarray(&config.groups, &config.numgroups, 200);
- for (j = k = 0; j < config.numgroups && config.groups[j] != NULL; j++) {
- char lbuf[64];
- int l = snprintf(lbuf, sizeof lbuf, "%s\"%s\"", k ? "," : "", config.groups[j]);
- if (l < 0)
- l = 0;
- if (l + k + 1 < len || extendline(&buf, &len, len + 1024) != -1) {
- strcpy(buf + k, lbuf);
- k += l;
- }
- }
+ for (j = 0; j < config.numgroups &&
+ config.groups[j] != NULL; j++)
+ sbuf_printf(buf, "%s\"%s\"", j ?
+ "," : "", config.groups[j]);
quote = 0;
break;
case _UC_DEFAULTCLASS:
- val = config.default_class ? config.default_class : "";
+ sbuf_cat(buf, config.default_class ?
+ config.default_class : "");
break;
case _UC_MINUID:
- sprintf(buf, "%lu", (unsigned long) config.min_uid);
+ sbuf_printf(buf, "%lu", (unsigned long) config.min_uid);
quote = 0;
break;
case _UC_MAXUID:
- sprintf(buf, "%lu", (unsigned long) config.max_uid);
+ sbuf_printf(buf, "%lu", (unsigned long) config.max_uid);
quote = 0;
break;
case _UC_MINGID:
- sprintf(buf, "%lu", (unsigned long) config.min_gid);
+ sbuf_printf(buf, "%lu", (unsigned long) config.min_gid);
quote = 0;
break;
case _UC_MAXGID:
- sprintf(buf, "%lu", (unsigned long) config.max_gid);
+ sbuf_printf(buf, "%lu", (unsigned long) config.max_gid);
quote = 0;
break;
case _UC_EXPIRE:
- sprintf(buf, "%d", config.expire_days);
+ sbuf_printf(buf, "%d", config.expire_days);
quote = 0;
break;
case _UC_PASSWORD:
- sprintf(buf, "%d", config.password_days);
+ sbuf_printf(buf, "%d", config.password_days);
quote = 0;
break;
case _UC_NONE:
break;
}
+ sbuf_finish(buf);
if (comments[i])
fputs(comments[i], fp);
if (*kwds[i]) {
if (quote)
- fprintf(fp, "%s = \"%s\"\n", kwds[i], val);
+ fprintf(fp, "%s = \"%s\"\n", kwds[i], sbuf_data(buf));
else
- fprintf(fp, "%s = %s\n", kwds[i], val);
+ fprintf(fp, "%s = %s\n", kwds[i], sbuf_data(buf));
#if debugging
- printf("WROTE: %s = %s\n", kwds[i], val);
+ printf("WROTE: %s = %s\n", kwds[i], sbuf_data(buf));
#endif
}
}
- free(buf);
+ sbuf_delete(buf);
return fclose(fp) != EOF;
}
}
diff --git a/usr.sbin/pw/pw_nis.c b/usr.sbin/pw/pw_nis.c
index 918fc30..c786cc7 100644
--- a/usr.sbin/pw/pw_nis.c
+++ b/usr.sbin/pw/pw_nis.c
@@ -29,9 +29,6 @@ static const char rcsid[] =
"$FreeBSD$";
#endif /* not lint */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#include <sys/types.h>
#include <err.h>
#include <pwd.h>
diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c
index 483148a..bdb3cd6 100644
--- a/usr.sbin/pw/pw_user.c
+++ b/usr.sbin/pw/pw_user.c
@@ -40,7 +40,6 @@ static const char rcsid[] =
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
-#include <unistd.h>
#include <login_cap.h>
#include <pwd.h>
#include <grp.h>
@@ -185,8 +184,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
* But we create a symlink from cnf->home -> "/usr" -> cnf->home
*/
if (strchr(cnf->home+1, '/') == NULL) {
- strcpy(dbuf, "/usr");
- strncat(dbuf, cnf->home, MAXPATHLEN-5);
+ snprintf(dbuf, MAXPATHLEN, "/usr%s", cnf->home);
if (mkdir(dbuf, _DEF_DIRMODE) != -1 || errno == EEXIST) {
chown(dbuf, 0, 0);
/*
@@ -364,11 +362,9 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
if (mode == M_LOCK) {
if (strncmp(pwd->pw_passwd, locked_str, sizeof(locked_str)-1) == 0)
errx(EX_DATAERR, "user '%s' is already locked", pwd->pw_name);
- passtmp = malloc(strlen(pwd->pw_passwd) + sizeof(locked_str));
+ asprintf(&passtmp, "%s%s", locked_str, pwd->pw_passwd);
if (passtmp == NULL) /* disaster */
errx(EX_UNAVAILABLE, "out of memory");
- strcpy(passtmp, locked_str);
- strcat(passtmp, pwd->pw_passwd);
pwd->pw_passwd = passtmp;
edited = 1;
} else if (mode == M_UNLOCK) {
OpenPOWER on IntegriCloud