Home | History | Annotate | Line # | Download | only in arm
      1 /*	$NetBSD: cpufunc_asm_arm11x6.S,v 1.10 2018/01/20 14:43:25 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2007 Microsoft
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. All advertising materials mentioning features or use of this software
     16  *    must display the following acknowledgement:
     17  *	This product includes software developed by Microsoft
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
     20  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     21  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     22  * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTERS BE LIABLE FOR ANY DIRECT,
     23  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     25  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29  * SUCH DAMAGE.
     30  */
     31 
     32 /*-
     33  * Copyright (c) 2012 The NetBSD Foundation, Inc.
     34  * All rights reserved.
     35  *
     36  * This code is derived from software contributed to The NetBSD Foundation
     37  * by Eben Upton
     38  *
     39  * Redistribution and use in source and binary forms, with or without
     40  * modification, are permitted provided that the following conditions
     41  * are met:
     42  * 1. Redistributions of source code must retain the above copyright
     43  *    notice, this list of conditions and the following disclaimer.
     44  * 2. Redistributions in binary form must reproduce the above copyright
     45  *    notice, this list of conditions and the following disclaimer in the
     46  *    documentation and/or other materials provided with the distribution.
     47  *
     48  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     49  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     50  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     51  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     52  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     53  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     54  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     55  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     56  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     57  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     58  * POSSIBILITY OF SUCH DAMAGE.
     59  */
     60 
     61 
     62 #include "assym.h"
     63 #include <machine/asm.h>
     64 #include <arm/locore.h>
     65 
     66 RCSID("$NetBSD: cpufunc_asm_arm11x6.S,v 1.10 2018/01/20 14:43:25 christos Exp $")
     67 
     68 #if 0
     69 #define Invalidate_I_cache(Rtmp1, Rtmp2) \
     70 	mcr	p15, 0, Rtmp1, c7, c5, 0	/* Invalidate Entire I cache */
     71 #else
     72 /*
     73  * Workaround for
     74  *
     75  *    Erratum 411920 in ARM1136 (fixed in r1p4)
     76  *    Erratum 415045 in ARM1176 (fixed in r0p5)
     77  *
     78  *	- value of arg 'reg' Should Be Zero
     79  */
     80 #define Invalidate_I_cache(Rtmp1, Rtmp2) \
     81 	mov	Rtmp1, #0;		/* SBZ */			\
     82 	mrs	Rtmp2, cpsr;						\
     83 	cpsid	ifa;							\
     84 	mcr	p15, 0, Rtmp1, c7, c5, 0;	/* Nuke Whole Icache */	\
     85 	mcr	p15, 0, Rtmp1, c7, c5, 0;	/* Nuke Whole Icache */	\
     86 	mcr	p15, 0, Rtmp1, c7, c5, 0;	/* Nuke Whole Icache */	\
     87 	mcr	p15, 0, Rtmp1, c7, c5, 0;	/* Nuke Whole Icache */	\
     88 	msr	cpsr_cx, Rtmp2;						\
     89 	nop;								\
     90 	nop;								\
     91 	nop;								\
     92 	nop;								\
     93 	nop;								\
     94 	nop;								\
     95 	nop;								\
     96 	nop;								\
     97 	nop;								\
     98 	nop;								\
     99 	nop;
    100 #endif
    101 
    102 #if 1
    103 #define Flush_D_cache(reg) \
    104 	mov	reg, #0;		/* SBZ */					\
    105 	mcr	p15, 0, reg, c7, c14, 0;/* Clean and Invalidate Entire Data Cache */	\
    106 	mcr	p15, 0, reg, c7, c10, 4;/* Data Synchronization Barrier */
    107 #else
    108 #define Flush_D_cache(reg) \
    109 1:	mov	reg, #0;		/* SBZ */					\
    110 	mcr	p15, 0, reg, c7, c14, 0;/* Clean and Invalidate Entire Data Cache */	\
    111 	mrc	p15, 0, reg, c7, c10, 6;/* Read Cache Dirty Status Register */		\
    112 	ands	reg, reg, #01;		/* Check if it is clean */			\
    113 	bne	1b;			/* loop if not */				\
    114 	mcr	p15, 0, reg, c7, c10, 4;/* Data Synchronization Barrier */
    115 #endif
    116 
    117 ENTRY_NP(arm11x6_idcache_wbinv_all)
    118 	Flush_D_cache(r0)
    119 	Invalidate_I_cache(r0, r1)
    120 	RET
    121 END(arm11x6_idcache_wbinv_all)
    122 
    123 ENTRY_NP(arm11x6_dcache_wbinv_all)
    124 	Flush_D_cache(r0)
    125 	RET
    126 END(arm11x6_dcache_wbinv_all)
    127 
    128 ENTRY_NP(arm11x6_icache_sync_all)
    129 	Flush_D_cache(r0)
    130 	Invalidate_I_cache(r0, r1)
    131 	RET
    132 END(arm11x6_icache_sync_all)
    133 
    134 ENTRY_NP(arm11x6_flush_prefetchbuf)
    135 	mcr	p15, 0, r0, c7, c5, 4	/* Flush Prefetch Buffer */
    136 	RET
    137 END(arm11x6_flush_prefetchbuf)
    138 
    139 ENTRY_NP(arm11x6_icache_sync_range)
    140 	ldr	r2, .Larm_pcache
    141 	ldr	r2, [r2, #DCACHE_SIZE]
    142 	cmp	r1, r2
    143 	bge	arm11x6_icache_sync_all
    144 
    145 	add	r1, r1, r0
    146 	sub	r1, r1, #1
    147 	/* Erratum ARM1136 371025, workaround #2 */
    148 	/* Erratum ARM1176 371367, workaround #2 */
    149 	mrs	r2, cpsr		/* save the CPSR */
    150 	cpsid	ifa			/* disable interrupts (irq,fiq,abort) */
    151 	mov	r3, #0
    152 	mcr	p15, 0, r3, c13, c0, 0	/* write FCSE (uTLB invalidate) */
    153 	mcr	p15, 0, r3, c7, c5, 4	/* flush prefetch buffer */
    154 	add	r3, pc, #0x24
    155 	mcr	p15, 0, r3, c7, c13, 1	/* prefetch I-cache line */
    156 	mcrr	p15, 0, r1, r0, c5	/* invalidate I-cache range */
    157 	msr	cpsr_cx, r2		/* local_irq_restore */
    158 	nop
    159 	nop
    160 	nop
    161 	nop
    162 	nop
    163 	nop
    164 	nop
    165 
    166 	mcrr	p15, 0, r1, r0, c12	/* clean D cache range */
    167 	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
    168 	RET
    169 END(arm11x6_icache_sync_range)
    170 
    171 ENTRY_NP(arm11x6_idcache_wbinv_range)
    172 	ldr	r2, .Larm_pcache
    173 	ldr	r2, [r2, #DCACHE_SIZE]
    174 	cmp	r1, r2
    175 	bge	arm11x6_idcache_wbinv_all
    176 
    177 	add	r1, r1, r0
    178 	sub	r1, r1, #1
    179 	/* Erratum ARM1136 371025, workaround #2 */
    180 	/* Erratum ARM1176 371367, workaround #2 */
    181 	mrs	r2, cpsr		/* save the CPSR */
    182 	cpsid	ifa			/* disable interrupts (irq,fiq,abort) */
    183 	mov	r3, #0
    184 	mcr	p15, 0, r3, c13, c0, 0	/* write FCSE (uTLB invalidate) */
    185 	mcr	p15, 0, r3, c7, c5, 4	/* flush prefetch buffer */
    186 	add	r3, pc, #0x24
    187 	mcr	p15, 0, r3, c7, c13, 1	/* prefetch I-cache line */
    188 	mcrr	p15, 0, r1, r0, c5	/* invalidate I-cache range */
    189 	msr	cpsr_cx, r2		/* local_irq_restore */
    190 	nop
    191 	nop
    192 	nop
    193 	nop
    194 	nop
    195 	nop
    196 	nop
    197 
    198 	mcrr	p15, 0, r1, r0, c14	/* clean and invalidate D cache range */
    199 	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
    200 	RET
    201 END(arm11x6_idcache_wbinv_range)
    202 
    203 /*
    204  * Preload the cache before issuing the WFI by conditionally disabling the
    205  * mcr intstructions the first time around the loop. Ensure the function is
    206  * cacheline aligned.
    207  */
    208 	.arch	armv6
    209 	.p2align 5
    210 
    211 ENTRY_NP(arm11x6_sleep)
    212 	mov	r0, #0
    213 	mov	r1, #2
    214 1:
    215 	subs	r1, #1
    216 	nop
    217 	mcreq	p15, 0, r0, c7, c10, 4		/* data sync barrier */
    218 	mcreq	p15, 0, r0, c7, c0, 4		/* wait for interrupt */
    219 	nop
    220 	nop
    221 	nop
    222 	bne	1b
    223 	RET
    224 END(arm11x6_sleep)
    225 
    226 .Larm_pcache:
    227 	.word arm_pcache
    228