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...
Dimitry Andric
dim at FreeBSD.org
Fri Feb 21 22:54:40 UTC 2014
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 at freebsd.org>
+ * Copyright (c) 2014 Steven Lawrance <stl at 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 ***
More information about the svn-src-projects
mailing list