Index: head/sys/arm/arm/cpufunc_asm_arm11.S =================================================================== --- head/sys/arm/arm/cpufunc_asm_arm11.S (revision 264159) +++ head/sys/arm/arm/cpufunc_asm_arm11.S (revision 264160) @@ -1,141 +1,135 @@ /* $NetBSD: cpufunc_asm_arm11.S,v 1.2 2005/12/11 12:16:41 christos Exp $ */ /* * Copyright (c) 2002, 2005 ARM Limited * 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. * * ARM11 assembly functions for CPU / MMU / TLB specific operations * * XXX We make no attempt at present to take advantage of the v6 memroy * architecture or physically tagged cache. */ #include __FBSDID("$FreeBSD$"); /* * 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(arm11_setttb) -#ifdef PMAP_CACHE_VIVT - stmfd sp!, {r0, lr} - bl _C_LABEL(armv5_idcache_wbinv_all) - ldmfd sp!, {r0, lr} -#endif - mcr p15, 0, r0, c2, c0, 0 /* load new TTB */ mcr p15, 0, r0, c8, c7, 0 /* invalidate I+D TLBs */ mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ RET END(arm11_setttb) /* * TLB functions */ ENTRY(arm11_tlb_flushID_SE) mcr p15, 0, r0, c8, c6, 1 /* flush D tlb single entry */ mcr p15, 0, r0, c8, c5, 1 /* flush I tlb single entry */ mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ RET END(arm11_tlb_flushID_SE) ENTRY(arm11_tlb_flushI_SE) mcr p15, 0, r0, c8, c5, 1 /* flush I tlb single entry */ mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ RET END(arm11_tlb_flushI_SE) /* * Context switch. * * These is the CPU-specific parts of the context switcher cpu_switch() * These functions actually perform the TTB reload. * * NOTE: Special calling convention * r1, r4-r13 must be preserved */ ENTRY(arm11_context_switch) /* * We can assume that the caches will only contain kernel addresses * at this point. So no need to flush them again. */ mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */ mcr p15, 0, r0, c2, c0, 0 /* set the new TTB */ mcr p15, 0, r0, c8, c7, 0 /* and flush the I+D tlbs */ /* Paranoia -- make sure the pipeline is empty. */ nop nop nop RET END(arm11_context_switch) /* * TLB functions */ ENTRY(arm11_tlb_flushID) mcr p15, 0, r0, c8, c7, 0 /* flush I+D tlb */ mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ mov pc, lr END(arm11_tlb_flushID) ENTRY(arm11_tlb_flushI) mcr p15, 0, r0, c8, c5, 0 /* flush I tlb */ mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ mov pc, lr END(arm11_tlb_flushI) ENTRY(arm11_tlb_flushD) mcr p15, 0, r0, c8, c6, 0 /* flush D tlb */ mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ mov pc, lr END(arm11_tlb_flushD) ENTRY(arm11_tlb_flushD_SE) mcr p15, 0, r0, c8, c6, 1 /* flush D tlb single entry */ mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ mov pc, lr END(arm11_tlb_flushD_SE) /* * Other functions */ ENTRY(arm11_drain_writebuf) mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ mov pc, lr END(arm11_drain_writebuf) ENTRY_NP(arm11_sleep) mov r0, #0 mcr p15, 0, r0, c7, c0, 4 /* wait for interrupt */ RET END(arm11_sleep) Index: head/sys/arm/arm/cpufunc_asm_arm11x6.S =================================================================== --- head/sys/arm/arm/cpufunc_asm_arm11x6.S (revision 264159) +++ head/sys/arm/arm/cpufunc_asm_arm11x6.S (revision 264160) @@ -1,227 +1,222 @@ /* $NetBSD: cpufunc_asm_arm11x6.S,v 1.1 2012/07/21 12:19:15 skrll Exp $ */ /* * 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. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Microsoft * * 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 CONTRIBUTERS 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. */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Eben Upton * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); .cpu arm1136js #if 0 #define Invalidate_I_cache(Rtmp1, Rtmp2) \ mcr p15, 0, Rtmp1, c7, c5, 0 /* Invalidate Entire I cache */ #else /* * Workaround for * * Erratum 411920 in ARM1136 (fixed in r1p4) * Erratum 415045 in ARM1176 (fixed in r0p5?) * * - value of arg 'reg' Should Be Zero */ #define Invalidate_I_cache(Rtmp1, Rtmp2) \ mov Rtmp1, #0; /* SBZ */ \ mrs Rtmp2, cpsr; \ cpsid ifa; \ mcr p15, 0, Rtmp1, c7, c5, 0; /* Nuke Whole Icache */ \ mcr p15, 0, Rtmp1, c7, c5, 0; /* Nuke Whole Icache */ \ mcr p15, 0, Rtmp1, c7, c5, 0; /* Nuke Whole Icache */ \ mcr p15, 0, Rtmp1, c7, c5, 0; /* Nuke Whole Icache */ \ msr cpsr_cx, Rtmp2; \ nop; \ nop; \ nop; \ nop; \ nop; \ nop; \ nop; \ nop; \ nop; \ nop; \ nop; #endif #if 1 #define Flush_D_cache(reg) \ mov reg, #0; /* SBZ */ \ mcr p15, 0, reg, c7, c14, 0;/* Clean and Invalidate Entire Data Cache */ \ mcr p15, 0, reg, c7, c10, 4;/* Data Synchronization Barrier */ #else #define Flush_D_cache(reg) \ 1: mov reg, #0; /* SBZ */ \ mcr p15, 0, reg, c7, c14, 0;/* Clean and Invalidate Entire Data Cache */ \ mrc p15, 0, reg, C7, C10, 6;/* Read Cache Dirty Status Register */ \ ands reg, reg, #01; /* Check if it is clean */ \ bne 1b; /* loop if not */ \ mcr p15, 0, reg, c7, c10, 4;/* Data Synchronization Barrier */ #endif ENTRY(arm11x6_setttb) -#ifdef PMAP_CACHE_VIVT - Flush_D_cache(r1) - Invalidate_I_cache(r1, r2) -#else mov r1, #0 -#endif mcr p15, 0, r0, c2, c0, 0 /* load new TTB */ mcr p15, 0, r1, c8, c7, 0 /* invalidate I+D TLBs */ mcr p15, 0, r1, c7, c10, 4 /* drain write buffer */ RET END(arm11x6_setttb) ENTRY_NP(arm11x6_idcache_wbinv_all) Flush_D_cache(r0) Invalidate_I_cache(r0, r1) RET END(arm11x6_idcache_wbinv_all) ENTRY_NP(arm11x6_dcache_wbinv_all) Flush_D_cache(r0) RET END(arm11x6_dcache_wbinv_all) ENTRY_NP(arm11x6_icache_sync_all) Flush_D_cache(r0) Invalidate_I_cache(r0, r1) RET END(arm11x6_icache_sync_all) ENTRY_NP(arm11x6_flush_prefetchbuf) mcr p15, 0, r0, c7, c5, 4 /* Flush Prefetch Buffer */ RET END(arm11x6_flush_prefetchbuf) ENTRY_NP(arm11x6_icache_sync_range) add r1, r1, r0 sub r1, r1, #1 /* Erratum ARM1136 371025, workaround #2 */ /* Erratum ARM1176 371367 */ mrs r2, cpsr /* save the CPSR */ cpsid ifa /* disable interrupts (irq,fiq,abort) */ mov r3, #0 mcr p15, 0, r3, c13, c0, 0 /* write FCSE (uTLB invalidate) */ mcr p15, 0, r3, c7, c5, 4 /* flush prefetch buffer */ add r3, pc, #0x24 mcr p15, 0, r3, c7, c13, 1 /* prefetch I-cache line */ mcrr p15, 0, r1, r0, c5 /* invalidate I-cache range */ msr cpsr_cx, r2 /* local_irq_restore */ nop nop nop nop nop nop nop mcrr p15, 0, r1, r0, c12 /* clean and invalidate D cache range */ /* XXXNH */ mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */ RET END(arm11x6_icache_sync_range) ENTRY_NP(arm11x6_idcache_wbinv_range) add r1, r1, r0 sub r1, r1, #1 /* Erratum ARM1136 371025, workaround #2 */ /* Erratum ARM1176 371367 */ mrs r2, cpsr /* save the CPSR */ cpsid ifa /* disable interrupts (irq,fiq,abort) */ mov r3, #0 mcr p15, 0, r3, c13, c0, 0 /* write FCSE (uTLB invalidate) */ mcr p15, 0, r3, c7, c5, 4 /* flush prefetch buffer */ add r3, pc, #0x24 mcr p15, 0, r3, c7, c13, 1 /* prefetch I-cache line */ mcrr p15, 0, r1, r0, c5 /* invalidate I-cache range */ msr cpsr_cx, r2 /* local_irq_restore */ nop nop nop nop nop nop nop mcrr p15, 0, r1, r0, c14 /* clean and invalidate D cache range */ mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */ RET END(arm11x6_idcache_wbinv_range) /* * Preload the cache before issuing the WFI by conditionally disabling the * mcr intstructions the first time around the loop. Ensure the function is * cacheline aligned. */ .arch armv6 .p2align 5 ENTRY_NP(arm11x6_sleep) mov r0, #0 mov r1, #2 1: subs r1, #1 nop mcreq p15, 0, r0, c7, c10, 4 /* data sync barrier */ mcreq p15, 0, r0, c7, c0, 4 /* wait for interrupt */ nop nop nop bne 1b RET END(arm11x6_sleep) Index: head/sys/arm/arm/cpufunc_asm_armv6.S =================================================================== --- head/sys/arm/arm/cpufunc_asm_armv6.S (revision 264159) +++ head/sys/arm/arm/cpufunc_asm_armv6.S (revision 264160) @@ -1,156 +1,152 @@ /* $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 END(armv6_setttb) /* * 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 END(armv6_icache_sync_range) /* 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 END(armv6_icache_sync_all) /* 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 END(armv6_dcache_wb_range) /* 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 END(armv6_dcache_wbinv_range) /* * 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 END(armv6_dcache_inv_range) /* 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 END(armv6_idcache_wbinv_range) /* 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 END(armv6_idcache_wbinv_all) END(armv6_dcache_wbinv_all) ENTRY(armv6_idcache_inv_all) mov r0, #0 mcr p15, 0, r0, c7, c7, 0 /* invalidate all I+D cache */ RET END(armv6_idcache_inv_all)