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 66RCSID("$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) \ 1091: 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 117ENTRY_NP(arm11x6_idcache_wbinv_all) 118 Flush_D_cache(r0) 119 Invalidate_I_cache(r0, r1) 120 RET 121END(arm11x6_idcache_wbinv_all) 122 123ENTRY_NP(arm11x6_dcache_wbinv_all) 124 Flush_D_cache(r0) 125 RET 126END(arm11x6_dcache_wbinv_all) 127 128ENTRY_NP(arm11x6_icache_sync_all) 129 Flush_D_cache(r0) 130 Invalidate_I_cache(r0, r1) 131 RET 132END(arm11x6_icache_sync_all) 133 134ENTRY_NP(arm11x6_flush_prefetchbuf) 135 mcr p15, 0, r0, c7, c5, 4 /* Flush Prefetch Buffer */ 136 RET 137END(arm11x6_flush_prefetchbuf) 138 139ENTRY_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 169END(arm11x6_icache_sync_range) 170 171ENTRY_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 201END(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 211ENTRY_NP(arm11x6_sleep) 212 mov r0, #0 213 mov r1, #2 2141: 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 224END(arm11x6_sleep) 225 226.Larm_pcache: 227 .word arm_pcache 228