Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 21 Feb 2014 22:54:36 +0000 (UTC)
From:      Dimitry Andric <dim@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r262312 - in projects/clang-sparc64: contrib/dma contrib/llvm/tools/clang/lib/Driver etc etc/dma etc/mtree etc/periodic/security lib/libc/sys libexec libexec/dma libexec/dma-mbox-create...
Message-ID:  <201402212254.s1LMsaA0005376@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dim
Date: Fri Feb 21 22:54:35 2014
New Revision: 262312
URL: http://svnweb.freebsd.org/changeset/base/262312

Log:
  Merge from head up to r262311.

Added:
  projects/clang-sparc64/contrib/dma/
     - copied from r262311, head/contrib/dma/
  projects/clang-sparc64/etc/dma/
     - copied from r262311, head/etc/dma/
  projects/clang-sparc64/libexec/dma/
     - copied from r262311, head/libexec/dma/
  projects/clang-sparc64/libexec/dma-mbox-create/
     - copied from r262311, head/libexec/dma-mbox-create/
  projects/clang-sparc64/tools/build/options/WITHOUT_DMA
     - copied unchanged from r262311, head/tools/build/options/WITHOUT_DMA
Modified:
  projects/clang-sparc64/contrib/llvm/tools/clang/lib/Driver/ToolChains.h
  projects/clang-sparc64/etc/Makefile
  projects/clang-sparc64/etc/mtree/BSD.root.dist
  projects/clang-sparc64/etc/mtree/BSD.var.dist
  projects/clang-sparc64/etc/periodic/security/800.loginfail
  projects/clang-sparc64/lib/libc/sys/mq_getattr.2
  projects/clang-sparc64/libexec/Makefile
  projects/clang-sparc64/libexec/rtld-elf/xmalloc.c
  projects/clang-sparc64/share/man/man4/ada.4
  projects/clang-sparc64/share/man/man5/src.conf.5
  projects/clang-sparc64/share/mk/bsd.own.mk
  projects/clang-sparc64/share/mk/bsd.sys.mk
  projects/clang-sparc64/sys/amd64/vmm/intel/vmx.c
  projects/clang-sparc64/sys/amd64/vmm/io/vlapic.c
  projects/clang-sparc64/sys/amd64/vmm/io/vlapic.h
  projects/clang-sparc64/sys/amd64/vmm/io/vlapic_priv.h
  projects/clang-sparc64/sys/arm/arm/machdep.c
  projects/clang-sparc64/sys/arm/freescale/imx/imx6_anatop.c
  projects/clang-sparc64/sys/arm/freescale/imx/imx6_anatopreg.h
  projects/clang-sparc64/sys/arm/freescale/imx/imx6_anatopvar.h
  projects/clang-sparc64/sys/boot/fdt/dts/imx6.dtsi
  projects/clang-sparc64/sys/kern/kern_descrip.c
  projects/clang-sparc64/tools/build/mk/OptionalObsoleteFiles.inc
  projects/clang-sparc64/usr.sbin/bhyve/pit_8254.c
  projects/clang-sparc64/usr.sbin/bhyve/virtio.h
Directory Properties:
  projects/clang-sparc64/   (props changed)
  projects/clang-sparc64/contrib/llvm/   (props changed)
  projects/clang-sparc64/contrib/llvm/tools/clang/   (props changed)
  projects/clang-sparc64/etc/   (props changed)
  projects/clang-sparc64/lib/libc/   (props changed)
  projects/clang-sparc64/share/man/man4/   (props changed)
  projects/clang-sparc64/sys/   (props changed)
  projects/clang-sparc64/sys/amd64/vmm/   (props changed)
  projects/clang-sparc64/sys/boot/   (props changed)
  projects/clang-sparc64/usr.sbin/bhyve/   (props changed)

Modified: projects/clang-sparc64/contrib/llvm/tools/clang/lib/Driver/ToolChains.h
==============================================================================
--- projects/clang-sparc64/contrib/llvm/tools/clang/lib/Driver/ToolChains.h	Fri Feb 21 22:45:35 2014	(r262311)
+++ projects/clang-sparc64/contrib/llvm/tools/clang/lib/Driver/ToolChains.h	Fri Feb 21 22:54:35 2014	(r262312)
@@ -512,7 +512,12 @@ public:
   virtual void
   AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
                                llvm::opt::ArgStringList &CC1Args) const;
-
+  virtual bool IsIntegratedAssemblerDefault() const {
+    if (getTriple().getArch() == llvm::Triple::ppc ||
+        getTriple().getArch() == llvm::Triple::ppc64)
+      return true;
+    return Generic_ELF::IsIntegratedAssemblerDefault();
+  }
 
   virtual bool UseSjLjExceptions() const;
 protected:

Modified: projects/clang-sparc64/etc/Makefile
==============================================================================
--- projects/clang-sparc64/etc/Makefile	Fri Feb 21 22:45:35 2014	(r262311)
+++ projects/clang-sparc64/etc/Makefile	Fri Feb 21 22:54:35 2014	(r262312)
@@ -226,6 +226,9 @@ distribution:
 .endif
 	${_+_}cd ${.CURDIR}/defaults; ${MAKE} install
 	${_+_}cd ${.CURDIR}/devd; ${MAKE} install
+.if ${MK_DMA} != "no"
+	${_+_}cd ${.CURDIR}/dma; ${MAKE} install
+.endif
 	${_+_}cd ${.CURDIR}/gss; ${MAKE} install
 	${_+_}cd ${.CURDIR}/periodic; ${MAKE} install
 .if ${MK_PKGBOOTSTRAP} != "no"

Modified: projects/clang-sparc64/etc/mtree/BSD.root.dist
==============================================================================
--- projects/clang-sparc64/etc/mtree/BSD.root.dist	Fri Feb 21 22:45:35 2014	(r262311)
+++ projects/clang-sparc64/etc/mtree/BSD.root.dist	Fri Feb 21 22:54:35 2014	(r262312)
@@ -32,6 +32,8 @@
         ..
         devd
         ..
+        dma
+        ..
         gnats
         ..
         gss

Modified: projects/clang-sparc64/etc/mtree/BSD.var.dist
==============================================================================
--- projects/clang-sparc64/etc/mtree/BSD.var.dist	Fri Feb 21 22:45:35 2014	(r262311)
+++ projects/clang-sparc64/etc/mtree/BSD.var.dist	Fri Feb 21 22:54:35 2014	(r262312)
@@ -74,6 +74,8 @@
     rwho            gname=daemon mode=0775
     ..
     spool
+        dma             uname=root gname=mail mode=0770
+        ..
         lock            uname=uucp gname=dialer mode=0775
         ..
 /set gname=daemon

Modified: projects/clang-sparc64/etc/periodic/security/800.loginfail
==============================================================================
--- projects/clang-sparc64/etc/periodic/security/800.loginfail	Fri Feb 21 22:45:35 2014	(r262311)
+++ projects/clang-sparc64/etc/periodic/security/800.loginfail	Fri Feb 21 22:54:35 2014	(r262312)
@@ -64,7 +64,7 @@ if check_yesno_period security_status_lo
 then
 	echo ""
 	echo "${host} login failures:"
-	n=$(catmsgs | egrep -ia "^$yesterday.*: .*(fail|invalid|bad|illegal)" |
+	n=$(catmsgs | egrep -ia "^$yesterday.*: .*\b(fail(ures?|ed)?|invalid|bad|illegal|auth.*error)\b" |
 	    tee /dev/stderr | wc -l)
 	[ $n -gt 0 ] && rc=1 || rc=0
 fi

Modified: projects/clang-sparc64/lib/libc/sys/mq_getattr.2
==============================================================================
--- projects/clang-sparc64/lib/libc/sys/mq_getattr.2	Fri Feb 21 22:45:35 2014	(r262311)
+++ projects/clang-sparc64/lib/libc/sys/mq_getattr.2	Fri Feb 21 22:54:35 2014	(r262312)
@@ -37,7 +37,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd November 29, 2005
+.Dd February 21, 2014
 .Dt MQ_GETATTR 2
 .Os
 .Sh NAME
@@ -83,8 +83,8 @@ structure referenced by the
 .Fa mqstat
 argument will be set to the current state
 of the message queue:
-.Bl -tag -width ".Va mq_flags"
-.It Va mq_flags
+.Bl -tag -width ".Va mq_curmsgs"
+.It Va mq_curmsgs
 The number of messages currently on the queue.
 .El
 .Sh RETURN VALUES

Modified: projects/clang-sparc64/libexec/Makefile
==============================================================================
--- projects/clang-sparc64/libexec/Makefile	Fri Feb 21 22:45:35 2014	(r262311)
+++ projects/clang-sparc64/libexec/Makefile	Fri Feb 21 22:54:35 2014	(r262312)
@@ -8,6 +8,8 @@ SUBDIR=	${_atf} \
 	bootpd \
 	${_casper} \
 	${_comsat} \
+	${_dma} \
+	${_dma-mbox-create} \
 	fingerd \
 	ftpd \
 	getty \
@@ -47,6 +49,11 @@ _casper=	casper
 _comsat=	comsat
 .endif
 
+.if ${MK_DMA} != "no"
+_dma=		dma
+_dma-mbox-create=	dma-mbox-create
+.endif
+
 .if ${MK_NIS} != "no"
 _mknetid=	mknetid
 _ypxfr=		ypxfr

Modified: projects/clang-sparc64/libexec/rtld-elf/xmalloc.c
==============================================================================
--- projects/clang-sparc64/libexec/rtld-elf/xmalloc.c	Fri Feb 21 22:45:35 2014	(r262311)
+++ projects/clang-sparc64/libexec/rtld-elf/xmalloc.c	Fri Feb 21 22:54:35 2014	(r262312)
@@ -72,14 +72,14 @@ void *
 malloc_aligned(size_t size, size_t align)
 {
 	void *mem, *res;
-	uintptr_t x;
-	size_t asize, r;
 
-	r = round(sizeof(void *), align);
-	asize = round(size, align) + r;
-	mem = xmalloc(asize);
-	x = (uintptr_t)mem;
-	res = (void *)round(x, align);
+	if (align & (sizeof(void *) -1)) {
+		rtld_fdputstr(STDERR_FILENO, "Invalid alignment\n");
+		_exit(1);
+	}
+
+	mem = xmalloc(size + sizeof(void *) + align - 1);
+	res = (void *)round((uintptr_t)mem + sizeof(void *), align);
 	*(void **)((uintptr_t)res - sizeof(void *)) = mem;
 	return (res);
 }

Modified: projects/clang-sparc64/share/man/man4/ada.4
==============================================================================
--- projects/clang-sparc64/share/man/man4/ada.4	Fri Feb 21 22:45:35 2014	(r262311)
+++ projects/clang-sparc64/share/man/man4/ada.4	Fri Feb 21 22:54:35 2014	(r262312)
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd February 8, 2012
+.Dd February 21, 2014
 .Dt ADA 4
 .Os
 .Sh NAME
@@ -129,8 +129,13 @@ The default is currently enabled.
 These variables determines whether device write cache should be enabled
 globally or per-device or disabled.
 Set to 1 to enable write cache, 0 to disable, -1 to leave it as-is.
-Values modified in runtime take effect only after device reset.
-The global default is currently enabled.
+Values modified at runtime take effect only after device reset 
+.Pq using the reset subcommand of Xr camcontrol 8 .
+Because of that, this setting should be changed in
+.Pa /boot/loader.conf
+instead of
+.Pa /etc/sysctl.conf .
+The global default is currently 1.
 The per-device default is to leave it as-is (follow global setting).
 .El
 .Sh FILES

Modified: projects/clang-sparc64/share/man/man5/src.conf.5
==============================================================================
--- projects/clang-sparc64/share/man/man5/src.conf.5	Fri Feb 21 22:45:35 2014	(r262311)
+++ projects/clang-sparc64/share/man/man5/src.conf.5	Fri Feb 21 22:54:35 2014	(r262312)
@@ -1,7 +1,7 @@
 .\" DO NOT EDIT-- this file is automatically generated.
 .\" from FreeBSD: head/tools/build/options/makeman 255964 2013-10-01 07:22:04Z des
 .\" $FreeBSD$
-.Dd January 30, 2014
+.Dd February 21, 2014
 .Dt SRC.CONF 5
 .Os
 .Sh NAME
@@ -326,6 +326,9 @@ and are located automatically by
 .It Va WITHOUT_DICT
 .\" from FreeBSD: head/tools/build/options/WITHOUT_DICT 156932 2006-03-21 07:50:50Z ru
 Set to not build the Webster dictionary files.
+.It Va WITHOUT_DMA
+.\" from FreeBSD: head/tools/build/options/WITHOUT_DMA 262282 2014-02-21 07:26:49Z bapt
+Set to not build dma Mail Transport Agent
 .It Va WITHOUT_DYNAMICROOT
 .\" from FreeBSD: head/tools/build/options/WITHOUT_DYNAMICROOT 156932 2006-03-21 07:50:50Z ru
 Set this if you do not want to link
@@ -672,6 +675,8 @@ When set, it also enforces the following
 .Pp
 .Bl -item -compact
 .It
+.Va WITHOUT_DMA
+.It
 .Va WITHOUT_MAILWRAPPER
 .It
 .Va WITHOUT_SENDMAIL

Modified: projects/clang-sparc64/share/mk/bsd.own.mk
==============================================================================
--- projects/clang-sparc64/share/mk/bsd.own.mk	Fri Feb 21 22:45:35 2014	(r262311)
+++ projects/clang-sparc64/share/mk/bsd.own.mk	Fri Feb 21 22:54:35 2014	(r262312)
@@ -271,6 +271,7 @@ __DEFAULT_YES_OPTIONS = \
     CTM \
     CXX \
     DICT \
+    DMA \
     DYNAMICROOT \
     ED_CRYPTO \
     EXAMPLES \
@@ -419,15 +420,6 @@ __DEFAULT_YES_OPTIONS+=GCC
 .else
 __DEFAULT_NO_OPTIONS+=GCC GNUCXX
 .endif
-# The libc++ headers use c++11 extensions.  These are normally silenced because
-# they are treated as system headers, but we explicitly disable that warning
-# suppression when building the base system to catch bugs in our headers.
-# Eventually we'll want to start building the base system C++ code as C++11,
-# but not yet.
-_COMPVERSION!= ${CC} --version
-.if ${_COMPVERSION:Mclang}
-CXXFLAGS+=	-Wno-c++11-extensions
-.endif
 .else
 # If clang is not cc, then build gcc by default
 __DEFAULT_NO_OPTIONS+=CLANG_IS_CC
@@ -520,6 +512,7 @@ MK_GROFF:=	no
 .if ${MK_MAIL} == "no"
 MK_MAILWRAPPER:= no
 MK_SENDMAIL:=	no
+MK_DMA:=	no
 .endif
 
 .if ${MK_NETGRAPH} == "no"

Modified: projects/clang-sparc64/share/mk/bsd.sys.mk
==============================================================================
--- projects/clang-sparc64/share/mk/bsd.sys.mk	Fri Feb 21 22:45:35 2014	(r262311)
+++ projects/clang-sparc64/share/mk/bsd.sys.mk	Fri Feb 21 22:54:35 2014	(r262312)
@@ -124,6 +124,12 @@ CFLAGS+=	 -Qunused-arguments
 # Don't emit .cfi directives, since we must use GNU as on sparc64, for now.
 CFLAGS+=	 -fno-dwarf2-cfi-asm
 .endif # SPARC64
+# The libc++ headers use c++11 extensions.  These are normally silenced because
+# they are treated as system headers, but we explicitly disable that warning
+# suppression when building the base system to catch bugs in our headers.
+# Eventually we'll want to start building the base system C++ code as C++11,
+# but not yet.
+CXXFLAGS+=	 -Wno-c++11-extensions
 CFLAGS+=	 ${CFLAGS.clang}
 CXXFLAGS+=	 ${CXXFLAGS.clang}
 .else # !CLANG

Modified: projects/clang-sparc64/sys/amd64/vmm/intel/vmx.c
==============================================================================
--- projects/clang-sparc64/sys/amd64/vmm/intel/vmx.c	Fri Feb 21 22:45:35 2014	(r262311)
+++ projects/clang-sparc64/sys/amd64/vmm/intel/vmx.c	Fri Feb 21 22:54:35 2014	(r262312)
@@ -113,6 +113,9 @@ __FBSDID("$FreeBSD$");
 #define	guest_msr_rw(vmx, msr) \
 	msr_bitmap_change_access((vmx)->msr_bitmap, (msr), MSR_BITMAP_ACCESS_RW)
 
+#define	guest_msr_ro(vmx, msr) \
+    msr_bitmap_change_access((vmx)->msr_bitmap, (msr), MSR_BITMAP_ACCESS_READ)
+
 #define	HANDLED		1
 #define	UNHANDLED	0
 
@@ -301,6 +304,54 @@ exit_reason_to_str(int reason)
 }
 #endif	/* KTR */
 
+static int
+vmx_allow_x2apic_msrs(struct vmx *vmx)
+{
+	int i, error;
+
+	error = 0;
+
+	/*
+	 * Allow readonly access to the following x2APIC MSRs from the guest.
+	 */
+	error += guest_msr_ro(vmx, MSR_APIC_ID);
+	error += guest_msr_ro(vmx, MSR_APIC_VERSION);
+	error += guest_msr_ro(vmx, MSR_APIC_LDR);
+	error += guest_msr_ro(vmx, MSR_APIC_SVR);
+
+	for (i = 0; i < 8; i++)
+		error += guest_msr_ro(vmx, MSR_APIC_ISR0 + i);
+
+	for (i = 0; i < 8; i++)
+		error += guest_msr_ro(vmx, MSR_APIC_TMR0 + i);
+	
+	for (i = 0; i < 8; i++)
+		error += guest_msr_ro(vmx, MSR_APIC_IRR0 + i);
+
+	error += guest_msr_ro(vmx, MSR_APIC_ESR);
+	error += guest_msr_ro(vmx, MSR_APIC_LVT_TIMER);
+	error += guest_msr_ro(vmx, MSR_APIC_LVT_THERMAL);
+	error += guest_msr_ro(vmx, MSR_APIC_LVT_PCINT);
+	error += guest_msr_ro(vmx, MSR_APIC_LVT_LINT0);
+	error += guest_msr_ro(vmx, MSR_APIC_LVT_LINT1);
+	error += guest_msr_ro(vmx, MSR_APIC_LVT_ERROR);
+	error += guest_msr_ro(vmx, MSR_APIC_ICR_TIMER);
+	error += guest_msr_ro(vmx, MSR_APIC_DCR_TIMER);
+	error += guest_msr_ro(vmx, MSR_APIC_ICR);
+
+	/*
+	 * Allow TPR, EOI and SELF_IPI MSRs to be read and written by the guest.
+	 *
+	 * These registers get special treatment described in the section
+	 * "Virtualizing MSR-Based APIC Accesses".
+	 */
+	error += guest_msr_rw(vmx, MSR_APIC_TPR);
+	error += guest_msr_rw(vmx, MSR_APIC_EOI);
+	error += guest_msr_rw(vmx, MSR_APIC_SELF_IPI);
+
+	return (error);
+}
+
 u_long
 vmx_fix_cr0(u_long cr0)
 {
@@ -1538,17 +1589,53 @@ ept_emulation_fault(uint64_t ept_qual)
 	return (TRUE);
 }
 
+static __inline int
+apic_access_virtualization(struct vmx *vmx, int vcpuid)
+{
+	uint32_t proc_ctls2;
+
+	proc_ctls2 = vmx->cap[vcpuid].proc_ctls2;
+	return ((proc_ctls2 & PROCBASED2_VIRTUALIZE_APIC_ACCESSES) ? 1 : 0);
+}
+
+static __inline int
+x2apic_virtualization(struct vmx *vmx, int vcpuid)
+{
+	uint32_t proc_ctls2;
+
+	proc_ctls2 = vmx->cap[vcpuid].proc_ctls2;
+	return ((proc_ctls2 & PROCBASED2_VIRTUALIZE_X2APIC_MODE) ? 1 : 0);
+}
+
 static int
-vmx_handle_apic_write(struct vlapic *vlapic, uint64_t qual)
+vmx_handle_apic_write(struct vmx *vmx, int vcpuid, struct vlapic *vlapic,
+    uint64_t qual)
 {
 	int error, handled, offset;
+	uint32_t *apic_regs, vector;
 	bool retu;
 
-	if (!virtual_interrupt_delivery)
-		return (UNHANDLED);
-
 	handled = HANDLED;
 	offset = APIC_WRITE_OFFSET(qual);
+
+	if (!apic_access_virtualization(vmx, vcpuid)) {
+		/*
+		 * In general there should not be any APIC write VM-exits
+		 * unless APIC-access virtualization is enabled.
+		 *
+		 * However self-IPI virtualization can legitimately trigger
+		 * an APIC-write VM-exit so treat it specially.
+		 */
+		if (x2apic_virtualization(vmx, vcpuid) &&
+		    offset == APIC_OFFSET_SELF_IPI) {
+			apic_regs = (uint32_t *)(vlapic->apic_page);
+			vector = apic_regs[APIC_OFFSET_SELF_IPI / 4];
+			vlapic_self_ipi_handler(vlapic, vector);
+			return (HANDLED);
+		} else
+			return (UNHANDLED);
+	}
+
 	switch (offset) {
 	case APIC_OFFSET_ID:
 		vlapic_id_write_handler(vlapic);
@@ -1589,10 +1676,10 @@ vmx_handle_apic_write(struct vlapic *vla
 }
 
 static bool
-apic_access_fault(uint64_t gpa)
+apic_access_fault(struct vmx *vmx, int vcpuid, uint64_t gpa)
 {
 
-	if (virtual_interrupt_delivery &&
+	if (apic_access_virtualization(vmx, vcpuid) &&
 	    (gpa >= DEFAULT_APIC_BASE && gpa < DEFAULT_APIC_BASE + PAGE_SIZE))
 		return (true);
 	else
@@ -1605,7 +1692,7 @@ vmx_handle_apic_access(struct vmx *vmx, 
 	uint64_t qual;
 	int access_type, offset, allowed;
 
-	if (!virtual_interrupt_delivery)
+	if (!apic_access_virtualization(vmx, vcpuid))
 		return (UNHANDLED);
 
 	qual = vmexit->u.vmx.exit_qualification;
@@ -1864,7 +1951,8 @@ vmx_exit_process(struct vmx *vmx, int vc
 		 * this must be an instruction that accesses MMIO space.
 		 */
 		gpa = vmcs_gpa();
-		if (vm_mem_allocated(vmx->vm, gpa) || apic_access_fault(gpa)) {
+		if (vm_mem_allocated(vmx->vm, gpa) ||
+		    apic_access_fault(vmx, vcpu, gpa)) {
 			vmexit->exitcode = VM_EXITCODE_PAGING;
 			vmexit->u.paging.gpa = gpa;
 			vmexit->u.paging.fault_type = ept_fault_type(qual);
@@ -1905,7 +1993,7 @@ vmx_exit_process(struct vmx *vmx, int vc
 		 */
 		vmexit->inst_length = 0;
 		vlapic = vm_lapic(vmx->vm, vcpu);
-		handled = vmx_handle_apic_write(vlapic, qual);
+		handled = vmx_handle_apic_write(vmx, vcpu, vlapic, qual);
 		break;
 	case EXIT_REASON_XSETBV:
 		handled = vmx_emulate_xsetbv(vmx, vcpu, vmexit);
@@ -2151,7 +2239,7 @@ vmx_vmcleanup(void *arg)
 	int i, error;
 	struct vmx *vmx = arg;
 
-	if (virtual_interrupt_delivery)
+	if (apic_access_virtualization(vmx, 0))
 		vm_unmap_mmio(vmx->vm, DEFAULT_APIC_BASE, PAGE_SIZE);
 
 	for (i = 0; i < VM_MAXCPU; i++)
@@ -2635,6 +2723,49 @@ vmx_set_tmr(struct vlapic *vlapic, int v
 }
 
 static void
+vmx_enable_x2apic_mode(struct vlapic *vlapic)
+{
+	struct vmx *vmx;
+	struct vmcs *vmcs;
+	uint32_t proc_ctls2;
+	int vcpuid, error;
+
+	vcpuid = vlapic->vcpuid;
+	vmx = ((struct vlapic_vtx *)vlapic)->vmx;
+	vmcs = &vmx->vmcs[vcpuid];
+
+	proc_ctls2 = vmx->cap[vcpuid].proc_ctls2;
+	KASSERT((proc_ctls2 & PROCBASED2_VIRTUALIZE_APIC_ACCESSES) != 0,
+	    ("%s: invalid proc_ctls2 %#x", __func__, proc_ctls2));
+
+	proc_ctls2 &= ~PROCBASED2_VIRTUALIZE_APIC_ACCESSES;
+	proc_ctls2 |= PROCBASED2_VIRTUALIZE_X2APIC_MODE;
+	vmx->cap[vcpuid].proc_ctls2 = proc_ctls2;
+
+	VMPTRLD(vmcs);
+	vmcs_write(VMCS_SEC_PROC_BASED_CTLS, proc_ctls2);
+	VMCLEAR(vmcs);
+
+	if (vlapic->vcpuid == 0) {
+		/*
+		 * The nested page table mappings are shared by all vcpus
+		 * so unmap the APIC access page just once.
+		 */
+		error = vm_unmap_mmio(vmx->vm, DEFAULT_APIC_BASE, PAGE_SIZE);
+		KASSERT(error == 0, ("%s: vm_unmap_mmio error %d",
+		    __func__, error));
+
+		/*
+		 * The MSR bitmap is shared by all vcpus so modify it only
+		 * once in the context of vcpu 0.
+		 */
+		error = vmx_allow_x2apic_msrs(vmx);
+		KASSERT(error == 0, ("%s: vmx_allow_x2apic_msrs error %d",
+		    __func__, error));
+	}
+}
+
+static void
 vmx_post_intr(struct vlapic *vlapic, int hostcpu)
 {
 
@@ -2739,6 +2870,7 @@ vmx_vlapic_init(void *arg, int vcpuid)
 		vlapic->ops.pending_intr = vmx_pending_intr;
 		vlapic->ops.intr_accepted = vmx_intr_accepted;
 		vlapic->ops.set_tmr = vmx_set_tmr;
+		vlapic->ops.enable_x2apic_mode = vmx_enable_x2apic_mode;
 	}
 
 	if (posted_interrupts)

Modified: projects/clang-sparc64/sys/amd64/vmm/io/vlapic.c
==============================================================================
--- projects/clang-sparc64/sys/amd64/vmm/io/vlapic.c	Fri Feb 21 22:45:35 2014	(r262311)
+++ projects/clang-sparc64/sys/amd64/vmm/io/vlapic.c	Fri Feb 21 22:54:35 2014	(r262312)
@@ -999,11 +999,13 @@ vlapic_icrlo_write_handler(struct vlapic
 	return (1);
 }
 
-static void
+void
 vlapic_self_ipi_handler(struct vlapic *vlapic, uint64_t val)
 {
 	int vec;
 
+	KASSERT(x2apic(vlapic), ("SELF_IPI does not exist in xAPIC mode"));
+
 	vec = val & 0xff;
 	lapic_intr_edge(vlapic->vm, vlapic->vcpuid, vec);
 	vmm_stat_array_incr(vlapic->vm, vlapic->vcpuid, IPIS_SENT,
@@ -1457,6 +1459,11 @@ vlapic_set_x2apic_state(struct vm *vm, i
 		lapic->ldr = 0;
 		lapic->dfr = 0xffffffff;
 	}
+
+	if (state == X2APIC_ENABLED) {
+		if (vlapic->ops.enable_x2apic_mode)
+			(*vlapic->ops.enable_x2apic_mode)(vlapic);
+	}
 }
 
 void

Modified: projects/clang-sparc64/sys/amd64/vmm/io/vlapic.h
==============================================================================
--- projects/clang-sparc64/sys/amd64/vmm/io/vlapic.h	Fri Feb 21 22:45:35 2014	(r262311)
+++ projects/clang-sparc64/sys/amd64/vmm/io/vlapic.h	Fri Feb 21 22:54:35 2014	(r262312)
@@ -102,4 +102,5 @@ int vlapic_icrlo_write_handler(struct vl
 void vlapic_icrtmr_write_handler(struct vlapic *vlapic);
 void vlapic_dcr_write_handler(struct vlapic *vlapic);
 void vlapic_lvt_write_handler(struct vlapic *vlapic, uint32_t offset);
+void vlapic_self_ipi_handler(struct vlapic *vlapic, uint64_t val);
 #endif	/* _VLAPIC_H_ */

Modified: projects/clang-sparc64/sys/amd64/vmm/io/vlapic_priv.h
==============================================================================
--- projects/clang-sparc64/sys/amd64/vmm/io/vlapic_priv.h	Fri Feb 21 22:45:35 2014	(r262311)
+++ projects/clang-sparc64/sys/amd64/vmm/io/vlapic_priv.h	Fri Feb 21 22:54:35 2014	(r262312)
@@ -144,6 +144,7 @@ struct vlapic_ops {
 	void (*intr_accepted)(struct vlapic *vlapic, int vector);
 	void (*post_intr)(struct vlapic *vlapic, int hostcpu);
 	void (*set_tmr)(struct vlapic *vlapic, int vector, bool level);
+	void (*enable_x2apic_mode)(struct vlapic *vlapic);
 };
 
 struct vlapic {

Modified: projects/clang-sparc64/sys/arm/arm/machdep.c
==============================================================================
--- projects/clang-sparc64/sys/arm/arm/machdep.c	Fri Feb 21 22:45:35 2014	(r262311)
+++ projects/clang-sparc64/sys/arm/arm/machdep.c	Fri Feb 21 22:54:35 2014	(r262312)
@@ -1167,7 +1167,6 @@ initarm(struct arm_boot_params *abp)
 	   (((uint32_t)(lastaddr) - KERNVIRTADDR) + PAGE_MASK) & ~PAGE_MASK,
 	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
 
-
 	/* Map L1 directory and allocated L2 page tables */
 	pmap_map_chunk(l1pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa,
 	    L1_TABLE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);

Modified: projects/clang-sparc64/sys/arm/freescale/imx/imx6_anatop.c
==============================================================================
--- projects/clang-sparc64/sys/arm/freescale/imx/imx6_anatop.c	Fri Feb 21 22:45:35 2014	(r262311)
+++ projects/clang-sparc64/sys/arm/freescale/imx/imx6_anatop.c	Fri Feb 21 22:54:35 2014	(r262312)
@@ -1,5 +1,6 @@
 /*-
  * Copyright (c) 2013 Ian Lepore <ian@freebsd.org>
+ * Copyright (c) 2014 Steven Lawrance <stl@koffein.net>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -29,6 +30,8 @@ __FBSDID("$FreeBSD$");
 
 /*
  * Analog PLL and power regulator driver for Freescale i.MX6 family of SoCs.
+ * Also, temperature montoring and cpu frequency control.  It was Freescale who
+ * kitchen-sinked this device, not us. :)
  *
  * We don't really do anything with analog PLLs, but the registers for
  * controlling them belong to the same block as the power regulator registers.
@@ -42,11 +45,19 @@ __FBSDID("$FreeBSD$");
  * I have no idea where the "anatop" name comes from.  It's in the standard DTS
  * source describing i.MX6 SoCs, and in the linux and u-boot code which comes
  * from Freescale, but it's not in the SoC manual.
+ *
+ * Note that temperature values throughout this code are handled in two types of
+ * units.  Items with '_cnt' in the name use the hardware temperature count
+ * units (higher counts are lower temperatures).  Items with '_val' in the name
+ * are deci-Celcius, which are converted to/from deci-Kelvins in the sysctl
+ * handlers (dK is the standard unit for temperature in sysctl).
  */
 
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/callout.h>
 #include <sys/kernel.h>
+#include <sys/sysctl.h>
 #include <sys/module.h>
 #include <sys/bus.h>
 #include <sys/rman.h>
@@ -56,68 +67,410 @@ __FBSDID("$FreeBSD$");
 
 #include <machine/bus.h>
 
+#include <arm/freescale/fsl_ocotpreg.h>
+#include <arm/freescale/fsl_ocotpvar.h>
 #include <arm/freescale/imx/imx6_anatopreg.h>
 #include <arm/freescale/imx/imx6_anatopvar.h>
 
+static struct resource_spec imx6_anatop_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+#define	MEMRES	0
+#define	IRQRES	1
+
 struct imx6_anatop_softc {
 	device_t	dev;
-	struct resource	*mem_res;
+	struct resource	*res[2];
+	uint32_t	cpu_curhz;
+	uint32_t	cpu_curmhz;
+	uint32_t	cpu_minhz;
+	uint32_t	cpu_maxhz;
+	uint32_t	refosc_hz;
+	void		*temp_intrhand;
+	uint32_t	temp_high_val;
+	uint32_t	temp_high_cnt;
+	uint32_t	temp_last_cnt;
+	uint32_t	temp_room_cnt;
+	struct callout	temp_throttle_callout;
+	sbintime_t	temp_throttle_delay;
+	uint32_t	temp_throttle_reset_cnt;
+	uint32_t	temp_throttle_trigger_cnt;
+	uint32_t	temp_throttle_val;
 };
 
 static struct imx6_anatop_softc *imx6_anatop_sc;
 
+/*
+ * Table of CPU max frequencies.  This is indexed by the max frequency value
+ * (0-3) from the ocotp CFG3 register.
+ */
+static uint32_t imx6_cpu_maxhz_tab[] = {
+	 792000000, 852000000, 996000000, 1200000000
+};
+
+#define	TZ_ZEROC	2732	/* deci-Kelvin <-> deci-Celcius offset. */
+
 uint32_t
 imx6_anatop_read_4(bus_size_t offset)
 {
 
-	return (bus_read_4(imx6_anatop_sc->mem_res, offset));
+	KASSERT(imx6_anatop_sc != NULL, ("imx6_anatop_read_4 sc NULL"));
+
+	return (bus_read_4(imx6_anatop_sc->res[MEMRES], offset));
 }
 
 void
 imx6_anatop_write_4(bus_size_t offset, uint32_t value)
 {
 
-	bus_write_4(imx6_anatop_sc->mem_res, offset, value);
+	KASSERT(imx6_anatop_sc != NULL, ("imx6_anatop_write_4 sc NULL"));
+
+	bus_write_4(imx6_anatop_sc->res[MEMRES], offset, value);
+}
+
+static inline uint32_t
+cpufreq_hz_from_div(struct imx6_anatop_softc *sc, uint32_t div)
+{
+
+	return (sc->refosc_hz * (div / 2));
+}
+
+static inline uint32_t
+cpufreq_hz_to_div(struct imx6_anatop_softc *sc, uint32_t cpu_hz)
+{
+
+	return (cpu_hz / (sc->refosc_hz / 2));
+}
+
+static inline uint32_t
+cpufreq_actual_hz(struct imx6_anatop_softc *sc, uint32_t cpu_hz)
+{
+
+	return (cpufreq_hz_from_div(sc, cpufreq_hz_to_div(sc, cpu_hz)));
+}
+
+static void 
+cpufreq_set_clock(struct imx6_anatop_softc * sc, uint32_t cpu_newhz)
+{
+	uint32_t div, timeout, wrk32;
+	const uint32_t mindiv =  54;
+	const uint32_t maxdiv = 108;
+
+	/*
+	 * Clip the requested frequency to the configured max, then clip the
+	 * resulting divisor to the documented min/max values.
+	 */
+	cpu_newhz = min(cpu_newhz, sc->cpu_maxhz);
+	div = cpufreq_hz_to_div(sc, cpu_newhz);
+	if (div < mindiv)
+		div = mindiv;
+	else if (div > maxdiv)
+		div = maxdiv;
+	sc->cpu_curhz = cpufreq_hz_from_div(sc, div);
+	sc->cpu_curmhz = sc->cpu_curhz / 1000000;
+
+	/*
+	 * I can't find a documented procedure for changing the ARM PLL divisor,
+	 * but some trial and error came up with this:
+	 *  - Set the bypass clock source to REF_CLK_24M (source #0).
+	 *  - Set the PLL into bypass mode; cpu should now be running at 24mhz.
+	 *  - Change the divisor.
+	 *  - Wait for the LOCK bit to come on; it takes ~50 loop iterations.
+	 *  - Turn off bypass mode; cpu should now be running at cpu_newhz.
+	 */
+	imx6_anatop_write_4(IMX6_ANALOG_CCM_PLL_ARM_CLR, 
+	    IMX6_ANALOG_CCM_PLL_ARM_CLK_SRC_MASK);
+	imx6_anatop_write_4(IMX6_ANALOG_CCM_PLL_ARM_SET, 
+	    IMX6_ANALOG_CCM_PLL_ARM_BYPASS);
+
+	wrk32 = imx6_anatop_read_4(IMX6_ANALOG_CCM_PLL_ARM);
+	wrk32 &= ~IMX6_ANALOG_CCM_PLL_ARM_DIV_MASK;
+	wrk32 |= div;
+	imx6_anatop_write_4(IMX6_ANALOG_CCM_PLL_ARM, wrk32);
+
+	timeout = 10000;
+	while ((imx6_anatop_read_4(IMX6_ANALOG_CCM_PLL_ARM) &
+	    IMX6_ANALOG_CCM_PLL_ARM_LOCK) == 0)
+		if (--timeout == 0)
+			panic("imx6_set_cpu_clock(): PLL never locked");
+
+	imx6_anatop_write_4(IMX6_ANALOG_CCM_PLL_ARM_CLR, 
+	    IMX6_ANALOG_CCM_PLL_ARM_BYPASS);
+}
+
+static void
+cpufreq_initialize(struct imx6_anatop_softc *sc)
+{
+	uint32_t cfg3speed;
+	struct sysctl_ctx_list *ctx;
+
+	ctx = device_get_sysctl_ctx(sc->dev);
+	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)),
+	    OID_AUTO, "cpu_mhz", CTLFLAG_RD, &sc->cpu_curmhz, 0, 
+	    "CPU frequency in MHz");
+
+	/*
+	 * XXX 24mhz shouldn't be hard-coded, should get this from imx6_ccm
+	 * (even though in the real world it will always be 24mhz).  Oh wait a
+	 * sec, I never wrote imx6_ccm.
+	 */
+	sc->refosc_hz = 24000000;
+
+	/*
+	 * Get the maximum speed this cpu can be set to.  The values in the
+	 * OCOTP CFG3 register are not documented in the reference manual.
+	 * The following info was in an archived email found via web search:
+	 *   - 2b'11: 1200000000Hz;
+	 *   - 2b'10: 996000000Hz;
+	 *   - 2b'01: 852000000Hz; -- i.MX6Q Only, exclusive with 996MHz.
+	 *   - 2b'00: 792000000Hz;
+	 */
+	cfg3speed = (fsl_ocotp_read_4(FSL_OCOTP_CFG3) & 
+	    FSL_OCOTP_CFG3_SPEED_MASK) >> FSL_OCOTP_CFG3_SPEED_SHIFT;
+
+	sc->cpu_minhz = cpufreq_actual_hz(sc, imx6_cpu_maxhz_tab[0]);
+	sc->cpu_maxhz = cpufreq_actual_hz(sc, imx6_cpu_maxhz_tab[cfg3speed]);
+
+	/*
+	 * Set the CPU to maximum speed.
+	 *
+	 * We won't have thermal throttling until interrupts are enabled, but we
+	 * want to run at full speed through all the device init stuff.  This
+	 * basically assumes that a single core can't overheat before interrupts
+	 * are enabled; empirical testing shows that to be a safe assumption.
+	 */
+	cpufreq_set_clock(sc, sc->cpu_maxhz);
+	device_printf(sc->dev, "CPU frequency %uMHz\n", sc->cpu_curmhz);
+}
+
+static inline uint32_t
+temp_from_count(struct imx6_anatop_softc *sc, uint32_t count)
+{
+
+	return (((sc->temp_high_val - (count - sc->temp_high_cnt) *
+	    (sc->temp_high_val - 250) / 
+	    (sc->temp_room_cnt - sc->temp_high_cnt))));
+}
+
+static inline uint32_t
+temp_to_count(struct imx6_anatop_softc *sc, uint32_t temp)
+{
+
+	return ((sc->temp_room_cnt - sc->temp_high_cnt) * 
+	    (sc->temp_high_val - temp) / (sc->temp_high_val - 250) + 
+	    sc->temp_high_cnt);
+}
+
+static void
+temp_update_count(struct imx6_anatop_softc *sc)
+{
+	uint32_t val;
+
+	val = imx6_anatop_read_4(IMX6_ANALOG_TEMPMON_TEMPSENSE0);
+	if (!(val & IMX6_ANALOG_TEMPMON_TEMPSENSE0_VALID))
+		return;
+	sc->temp_last_cnt =
+	    (val & IMX6_ANALOG_TEMPMON_TEMPSENSE0_TEMP_CNT_MASK) >>
+	    IMX6_ANALOG_TEMPMON_TEMPSENSE0_TEMP_CNT_SHIFT;
 }
 
 static int
-imx6_anatop_detach(device_t dev)
+temp_sysctl_handler(SYSCTL_HANDLER_ARGS)
 {
-	struct imx6_anatop_softc *sc;
+	struct imx6_anatop_softc *sc = arg1;
+	uint32_t t;
 
-	sc = device_get_softc(dev);
+	temp_update_count(sc);
 
-	if (sc->mem_res != NULL)
-		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res);
+	t = temp_from_count(sc, sc->temp_last_cnt) + TZ_ZEROC;
 
-	return (0);
+	return (sysctl_handle_int(oidp, &t, 0, req));
+}
+
+static int
+temp_throttle_sysctl_handler(SYSCTL_HANDLER_ARGS)
+{
+	struct imx6_anatop_softc *sc = arg1;
+	int err;
+	uint32_t temp;
+
+	temp = sc->temp_throttle_val + TZ_ZEROC;
+	err = sysctl_handle_int(oidp, &temp, 0, req);
+	if (temp < TZ_ZEROC)
+		return (ERANGE);
+	temp -= TZ_ZEROC;
+	if (err != 0 || req->newptr == NULL || temp == sc->temp_throttle_val)
+		return (err);
+
+	/* Value changed, update counts in softc and hardware. */
+	sc->temp_throttle_val = temp;
+	sc->temp_throttle_trigger_cnt = temp_to_count(sc, sc->temp_throttle_val);
+	sc->temp_throttle_reset_cnt = temp_to_count(sc, sc->temp_throttle_val - 100);
+	imx6_anatop_write_4(IMX6_ANALOG_TEMPMON_TEMPSENSE0_CLR,
+	    IMX6_ANALOG_TEMPMON_TEMPSENSE0_ALARM_MASK);
+	imx6_anatop_write_4(IMX6_ANALOG_TEMPMON_TEMPSENSE0_SET,
+	    (sc->temp_throttle_trigger_cnt <<
+	     IMX6_ANALOG_TEMPMON_TEMPSENSE0_ALARM_SHIFT));
+	return (err);
+}
+
+static void
+tempmon_gofast(struct imx6_anatop_softc *sc)
+{
+
+	if (sc->cpu_curhz < sc->cpu_maxhz) {
+		cpufreq_set_clock(sc, sc->cpu_maxhz);
+	}
+}
+
+static void
+tempmon_goslow(struct imx6_anatop_softc *sc)
+{
+
+	if (sc->cpu_curhz > sc->cpu_minhz) {
+		cpufreq_set_clock(sc, sc->cpu_minhz);
+	}
+}
+
+static int
+tempmon_intr(void *arg)
+{
+	struct imx6_anatop_softc *sc = arg;
+
+	/*
+	 * XXX Note that this code doesn't currently run (for some mysterious
+	 * reason we just never get an interrupt), so the real monitoring is
+	 * done by tempmon_throttle_check().
+	 */
+	tempmon_goslow(sc);
+	/* XXX Schedule callout to speed back up eventually. */
+	return (FILTER_HANDLED);
+}
+
+static void
+tempmon_throttle_check(void *arg)
+{
+	struct imx6_anatop_softc *sc = arg;
+
+	/* Lower counts are higher temperatures. */
+	if (sc->temp_last_cnt < sc->temp_throttle_trigger_cnt)
+		tempmon_goslow(sc);
+	else if (sc->temp_last_cnt > (sc->temp_throttle_reset_cnt))
+		tempmon_gofast(sc);
+
+	callout_reset_sbt(&sc->temp_throttle_callout, sc->temp_throttle_delay,
+		0, tempmon_throttle_check, sc, 0);
+
+}
+
+static void
+initialize_tempmon(struct imx6_anatop_softc *sc)
+{
+	uint32_t cal;
+	struct sysctl_ctx_list *ctx;
+
+	/*
+	 * Fetch calibration data: a sensor count at room temperature (25C),
+	 * a sensor count at a high temperature, and that temperature
+	 */
+	cal = fsl_ocotp_read_4(FSL_OCOTP_ANA1);
+	sc->temp_room_cnt = (cal & 0xFFF00000) >> 20;
+	sc->temp_high_cnt = (cal & 0x000FFF00) >> 8;
+	sc->temp_high_val = (cal & 0x000000FF) * 10;
+
+	/*
+	 * Throttle to a lower cpu freq at 10C below the "hot" temperature, and
+	 * reset back to max cpu freq at 5C below the trigger.
+	 */
+	sc->temp_throttle_val = sc->temp_high_val - 100;
+	sc->temp_throttle_trigger_cnt =
+	    temp_to_count(sc, sc->temp_throttle_val);
+	sc->temp_throttle_reset_cnt = 
+	    temp_to_count(sc, sc->temp_throttle_val - 50);
+
+	/*
+	 * Set the sensor to sample automatically at 16Hz (32.768KHz/0x800), set
+	 * the throttle count, and begin making measurements.
+	 */
+	imx6_anatop_write_4(IMX6_ANALOG_TEMPMON_TEMPSENSE1, 0x0800);
+	imx6_anatop_write_4(IMX6_ANALOG_TEMPMON_TEMPSENSE0,
+	    (sc->temp_throttle_trigger_cnt << 
+	    IMX6_ANALOG_TEMPMON_TEMPSENSE0_ALARM_SHIFT) |
+	    IMX6_ANALOG_TEMPMON_TEMPSENSE0_MEASURE);
+
+	/*
+	 * XXX Note that the alarm-interrupt feature isn't working yet, so
+	 * we'll use a callout handler to check at 10Hz.  Make sure we have an
+	 * initial temperature reading before starting up the callouts so we
+	 * don't get a bogus reading of zero.
+	 */
+	while (sc->temp_last_cnt == 0)
+		temp_update_count(sc);
+	sc->temp_throttle_delay = 100 * SBT_1MS;
+	callout_init(&sc->temp_throttle_callout, 0);
+	callout_reset_sbt(&sc->temp_throttle_callout, sc->temp_throttle_delay, 
+	    0, tempmon_throttle_check, sc, 0);
+
+	ctx = device_get_sysctl_ctx(sc->dev);
+	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)),
+	    OID_AUTO, "temperature", CTLTYPE_INT | CTLFLAG_RD, sc, 0,
+	    temp_sysctl_handler, "IK", "Current die temperature");
+	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)),
+	    OID_AUTO, "throttle_temperature", CTLTYPE_INT | CTLFLAG_RW, sc,
+	    0, temp_throttle_sysctl_handler, "IK", 
+	    "Throttle CPU when exceeding this temperature");
+}
+
+static int
+imx6_anatop_detach(device_t dev)
+{
+
+	return (EBUSY);
 }
 
 static int
 imx6_anatop_attach(device_t dev)
 {
 	struct imx6_anatop_softc *sc;
-	int err, rid;
+	int err;
 
 	sc = device_get_softc(dev);
+	sc->dev = dev;
 
 	/* Allocate bus_space resources. */
-	rid = 0;
-	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
-	    RF_ACTIVE);
-	if (sc->mem_res == NULL) {
-		device_printf(dev, "Cannot allocate memory resources\n");
+	if (bus_alloc_resources(dev, imx6_anatop_spec, sc->res)) {
+		device_printf(dev, "Cannot allocate resources\n");
 		err = ENXIO;
 		goto out;
 	}
 
+	err = bus_setup_intr(dev, sc->res[IRQRES], INTR_TYPE_MISC | INTR_MPSAFE,
+	    tempmon_intr, NULL, sc, &sc->temp_intrhand);
+	if (err != 0)
+		goto out;
+
 	imx6_anatop_sc = sc;
+
+	/*
+	 * Other code seen on the net sets this SELFBIASOFF flag around the same
+	 * time the temperature sensor is set up, although it's unclear how the
+	 * two are related (if at all).
+	 */
+	imx6_anatop_write_4(IMX6_ANALOG_PMU_MISC0_SET, 
+	    IMX6_ANALOG_PMU_MISC0_SELFBIASOFF);
+
+	cpufreq_initialize(sc);
+	initialize_tempmon(sc);
+
 	err = 0;
 
 out:
 
-	if (err != 0)
-		imx6_anatop_detach(dev);
+	if (err != 0) {
+		bus_release_resources(dev, imx6_anatop_spec, sc->res);
+	}
 
 	return (err);
 }
@@ -129,7 +482,7 @@ imx6_anatop_probe(device_t dev)
 	if (!ofw_bus_status_okay(dev))
 		return (ENXIO);
 
-        if (ofw_bus_is_compatible(dev, "fsl,imx6q-anatop") == 0)
+	if (ofw_bus_is_compatible(dev, "fsl,imx6q-anatop") == 0)
 		return (ENXIO);
 

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201402212254.s1LMsaA0005376>