From owner-svn-src-all@FreeBSD.ORG Sun Aug 26 02:23:22 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A59FB1065673; Sun, 26 Aug 2012 02:23:22 +0000 (UTC) (envelope-from gonzo@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 8EB408FC16; Sun, 26 Aug 2012 02:23:22 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q7Q2NMGD040542; Sun, 26 Aug 2012 02:23:22 GMT (envelope-from gonzo@svn.freebsd.org) Received: (from gonzo@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q7Q2NMv1040538; Sun, 26 Aug 2012 02:23:22 GMT (envelope-from gonzo@svn.freebsd.org) Message-Id: <201208260223.q7Q2NMv1040538@svn.freebsd.org> From: Oleksandr Tymoshenko Date: Sun, 26 Aug 2012 02:23:22 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r239701 - in head/sys/arm: arm include X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 26 Aug 2012 02:23:22 -0000 Author: gonzo Date: Sun Aug 26 02:23:21 2012 New Revision: 239701 URL: http://svn.freebsd.org/changeset/base/239701 Log: Add support for ARM11 cpufunc Obtained from: NetBSD (partially) Added: head/sys/arm/arm/cpufunc_asm_armv6.S (contents, props changed) Modified: head/sys/arm/arm/cpufunc.c head/sys/arm/include/cpufunc.h Modified: head/sys/arm/arm/cpufunc.c ============================================================================== --- head/sys/arm/arm/cpufunc.c Sun Aug 26 01:41:41 2012 (r239700) +++ head/sys/arm/arm/cpufunc.c Sun Aug 26 02:23:21 2012 (r239701) @@ -968,6 +968,68 @@ struct cpu_functions fa526_cpufuncs = { }; #endif /* CPU_FA526 || CPU_FA626TE */ +#if defined(CPU_ARM11) +struct cpu_functions arm11_cpufuncs = { + /* CPU functions */ + + cpufunc_id, /* id */ + arm11_drain_writebuf, /* cpwait */ + + /* MMU functions */ + + cpufunc_control, /* control */ + cpufunc_domains, /* Domain */ + arm11_setttb, /* Setttb */ + cpufunc_faultstatus, /* Faultstatus */ + cpufunc_faultaddress, /* Faultaddress */ + + /* TLB functions */ + + arm11_tlb_flushID, /* tlb_flushID */ + arm11_tlb_flushID_SE, /* tlb_flushID_SE */ + arm11_tlb_flushI, /* tlb_flushI */ + arm11_tlb_flushI_SE, /* tlb_flushI_SE */ + arm11_tlb_flushD, /* tlb_flushD */ + arm11_tlb_flushD_SE, /* tlb_flushD_SE */ + + /* Cache operations */ + + armv6_icache_sync_all, /* icache_sync_all */ + armv6_icache_sync_range, /* icache_sync_range */ + + armv6_dcache_wbinv_all, /* dcache_wbinv_all */ + armv6_dcache_wbinv_range, /* dcache_wbinv_range */ + armv6_dcache_inv_range, /* dcache_inv_range */ + armv6_dcache_wb_range, /* dcache_wb_range */ + + armv6_idcache_wbinv_all, /* idcache_wbinv_all */ + armv6_idcache_wbinv_range, /* idcache_wbinv_range */ + + (void*)cpufunc_nullop, /* l2cache_wbinv_all */ + (void *)cpufunc_nullop, /* l2cache_wbinv_range */ + (void *)cpufunc_nullop, /* l2cache_inv_range */ + (void *)cpufunc_nullop, /* l2cache_wb_range */ + + /* Other functions */ + + cpufunc_nullop, /* flush_prefetchbuf */ + arm11_drain_writebuf, /* drain_writebuf */ + cpufunc_nullop, /* flush_brnchtgt_C */ + (void *)cpufunc_nullop, /* flush_brnchtgt_E */ + + arm11_sleep, /* sleep */ + + /* Soft functions */ + + cpufunc_null_fixup, /* dataabt_fixup */ + cpufunc_null_fixup, /* prefetchabt_fixup */ + + arm11_context_switch, /* context_switch */ + + arm11_setup /* cpu setup */ +}; +#endif /* CPU_ARM11 */ + #if defined(CPU_CORTEXA) struct cpu_functions cortexa_cpufuncs = { /* CPU functions */ @@ -1324,6 +1386,15 @@ set_cpufuncs() goto out; } #endif /* CPU_ARM10 */ +#ifdef CPU_ARM11 + cpufuncs = arm11_cpufuncs; + cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */ + get_cachetype_cp15(); + + pmap_pte_init_mmu_v6(); + + goto out; +#endif /* CPU_ARM11 */ #ifdef CPU_CORTEXA if (cputype == CPU_ID_CORTEXA8R1 || cputype == CPU_ID_CORTEXA8R2 || @@ -2197,38 +2268,36 @@ void arm11_setup(args) char *args; { - int cpuctrl, cpuctrlmask; - - cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE - | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE - /* | CPU_CONTROL_BPRD_ENABLE */; - cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE - | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE - | CPU_CONTROL_ROM_ENABLE | CPU_CONTROL_BPRD_ENABLE - | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE - | CPU_CONTROL_ROUNDROBIN | CPU_CONTROL_CPCLK; + int cpuctrl; + cpuctrl = CPU_CONTROL_MMU_ENABLE; #ifndef ARM32_DISABLE_ALIGNMENT_FAULTS cpuctrl |= CPU_CONTROL_AFLT_ENABLE; #endif - + cpuctrl |= CPU_CONTROL_DC_ENABLE; + cpuctrl |= (0xf << 3); cpuctrl = parse_cpu_options(args, arm11_options, cpuctrl); - #ifdef __ARMEB__ cpuctrl |= CPU_CONTROL_BEND_ENABLE; #endif + cpuctrl |= CPU_CONTROL_SYST_ENABLE; + cpuctrl |= CPU_CONTROL_BPRD_ENABLE; + cpuctrl |= CPU_CONTROL_IC_ENABLE; + if (vector_page == ARM_VECTORS_HIGH) + cpuctrl |= CPU_CONTROL_VECRELOC; + cpuctrl |= (0x5 << 16); + cpuctrl |= CPU_CONTROL_V6_EXTPAGE; - /* Clear out the cache */ + /* Make sure caches are clean. */ cpu_idcache_wbinv_all(); - - /* Now really make sure they are clean. */ - __asm __volatile ("mcr\tp15, 0, r0, c7, c7, 0" : : ); + cpu_l2cache_wbinv_all(); /* Set the control register */ + ctrl = cpuctrl; cpu_control(0xffffffff, cpuctrl); - /* And again. */ cpu_idcache_wbinv_all(); + cpu_l2cache_wbinv_all(); } #endif /* CPU_ARM11 */ Added: head/sys/arm/arm/cpufunc_asm_armv6.S ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/arm/arm/cpufunc_asm_armv6.S Sun Aug 26 02:23:21 2012 (r239701) @@ -0,0 +1,140 @@ +/* $NetBSD: cpufunc_asm_armv6.S,v 1.4 2010/12/10 02:06:22 bsh Exp $ */ + +/* + * Copyright (c) 2002, 2005 ARM Limited + * Portions Copyright (c) 2007 Microsoft + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the company may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ARMv6 assembly functions for manipulating caches. + * These routines can be used by any core that supports the mcrr address + * range operations. + */ + +/* + * $FreeBSD$ + */ + +#include + + .arch armv6 + +/* + * Functions to set the MMU Translation Table Base register + * + * We need to clean and flush the cache as it uses virtual + * addresses that are about to change. + */ +ENTRY(armv6_setttb) +#ifdef PMAP_CACHE_VIVT + mcr p15, 0, r0, c7, c5, 0 /* Flush I cache */ + mcr p15, 0, r0, c7, c14, 0 /* clean and invalidate D cache */ +#endif + mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */ + + mcr p15, 0, r0, c2, c0, 0 /* load new TTB */ + + mcr p15, 0, r0, c8, c7, 0 /* invalidate I+D TLBs */ + RET + +/* + * Cache operations. + */ + +/* LINTSTUB: void armv6_icache_sync_range(vaddr_t, vsize_t); */ +ENTRY_NP(armv6_icache_sync_range) + add r1, r1, r0 + sub r1, r1, #1 + mcrr p15, 0, r1, r0, c5 /* invalidate I cache range */ + mcrr p15, 0, r1, r0, c12 /* clean D cache range */ + mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */ + RET + +/* LINTSTUB: void armv6_icache_sync_all(void); */ +ENTRY_NP(armv6_icache_sync_all) + /* + * We assume that the code here can never be out of sync with the + * dcache, so that we can safely flush the Icache and fall through + * into the Dcache cleaning code. + */ + mcr p15, 0, r0, c7, c5, 0 /* Flush I cache */ + mcr p15, 0, r0, c7, c10, 0 /* Clean D cache */ + mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */ + RET + +/* LINTSTUB: void armv6_dcache_wb_range(vaddr_t, vsize_t); */ +ENTRY(armv6_dcache_wb_range) + add r1, r1, r0 + sub r1, r1, #1 + mcrr p15, 0, r1, r0, c12 /* clean D cache range */ + mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */ + RET + +/* LINTSTUB: void armv6_dcache_wbinv_range(vaddr_t, vsize_t); */ +ENTRY(armv6_dcache_wbinv_range) + add r1, r1, r0 + sub r1, r1, #1 + mcrr p15, 0, r1, r0, c14 /* clean and invaliate D cache range */ + mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */ + RET + +/* + * Note, we must not invalidate everything. If the range is too big we + * must use wb-inv of the entire cache. + * + * LINTSTUB: void armv6_dcache_inv_range(vaddr_t, vsize_t); + */ +ENTRY(armv6_dcache_inv_range) + add r1, r1, r0 + sub r1, r1, #1 + mcrr p15, 0, r1, r0, c6 /* invaliate D cache range */ + mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */ + RET + +/* LINTSTUB: void armv6_idcache_wbinv_range(vaddr_t, vsize_t); */ +ENTRY(armv6_idcache_wbinv_range) + add r1, r1, r0 + sub r1, r1, #1 + mcrr p15, 0, r1, r0, c5 /* invaliate I cache range */ + mcrr p15, 0, r1, r0, c14 /* clean & invaliate D cache range */ + mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */ + RET + +/* LINTSTUB: void armv6_idcache_wbinv_all(void); */ +ENTRY_NP(armv6_idcache_wbinv_all) + /* + * We assume that the code here can never be out of sync with the + * dcache, so that we can safely flush the Icache and fall through + * into the Dcache purging code. + */ + mcr p15, 0, r0, c7, c5, 0 /* Flush I cache */ + /* Fall through to purge Dcache. */ + +/* LINTSTUB: void armv6_dcache_wbinv_all(void); */ +ENTRY(armv6_dcache_wbinv_all) + mcr p15, 0, r0, c7, c14, 0 /* clean & invalidate D cache */ + mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */ + RET Modified: head/sys/arm/include/cpufunc.h ============================================================================== --- head/sys/arm/include/cpufunc.h Sun Aug 26 01:41:41 2012 (r239700) +++ head/sys/arm/include/cpufunc.h Sun Aug 26 02:23:21 2012 (r239701) @@ -495,8 +495,15 @@ void pj4b_flush_brnchtgt_va (u_int); void pj4b_sleep (int); void armv6_icache_sync_all (void); +void armv6_icache_sync_range (vm_offset_t, vm_size_t); + void armv6_dcache_wbinv_all (void); +void armv6_dcache_wbinv_range (vm_offset_t, vm_size_t); +void armv6_dcache_inv_range (vm_offset_t, vm_size_t); +void armv6_dcache_wb_range (vm_offset_t, vm_size_t); + void armv6_idcache_wbinv_all (void); +void armv6_idcache_wbinv_range (vm_offset_t, vm_size_t); void armv7_setttb (u_int); void armv7_tlb_flushID (void);