From owner-svn-src-projects@FreeBSD.ORG Fri Feb 21 22:54:40 2014 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id F334BC38; Fri, 21 Feb 2014 22:54:39 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id DBB0316C2; Fri, 21 Feb 2014 22:54:39 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s1LMsdmJ005398; Fri, 21 Feb 2014 22:54:39 GMT (envelope-from dim@svn.freebsd.org) Received: (from dim@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s1LMsaA0005376; Fri, 21 Feb 2014 22:54:36 GMT (envelope-from dim@svn.freebsd.org) Message-Id: <201402212254.s1LMsaA0005376@svn.freebsd.org> From: Dimitry Andric Date: Fri, 21 Feb 2014 22:54:36 +0000 (UTC) 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... X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 21 Feb 2014 22:54:40 -0000 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 + * Copyright (c) 2014 Steven Lawrance * 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 #include +#include #include +#include #include #include #include @@ -56,68 +67,410 @@ __FBSDID("$FreeBSD$"); #include +#include +#include #include #include +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 ***