1/* $NetBSD: cpufunc_asm_xscale.S,v 1.16 2002/08/17 16:36:32 thorpej Exp $ */ 2 3/*- 4 * Copyright (c) 2007 Olivier Houchard 5 * Copyright (c) 2001, 2002 Wasabi Systems, Inc. 6 * All rights reserved. 7 * 8 * Written by Allen Briggs and Jason R. Thorpe for Wasabi Systems, Inc. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed for the NetBSD Project by 21 * Wasabi Systems, Inc. 22 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 23 * or promote products derived from this software without specific prior 24 * written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 * 38 */ 39 40/*- 41 * Copyright (c) 2001 Matt Thomas. 42 * Copyright (c) 1997,1998 Mark Brinicombe. 43 * Copyright (c) 1997 Causality Limited 44 * All rights reserved. 45 * 46 * Redistribution and use in source and binary forms, with or without 47 * modification, are permitted provided that the following conditions 48 * are met: 49 * 1. Redistributions of source code must retain the above copyright 50 * notice, this list of conditions and the following disclaimer. 51 * 2. Redistributions in binary form must reproduce the above copyright 52 * notice, this list of conditions and the following disclaimer in the 53 * documentation and/or other materials provided with the distribution. 54 * 3. All advertising materials mentioning features or use of this software 55 * must display the following acknowledgement: 56 * This product includes software developed by Causality Limited. 57 * 4. The name of Causality Limited may not be used to endorse or promote 58 * products derived from this software without specific prior written 59 * permission. 60 * 61 * THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``AS IS'' AND ANY EXPRESS 62 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 63 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 64 * DISCLAIMED. IN NO EVENT SHALL CAUSALITY LIMITED BE LIABLE FOR ANY DIRECT, 65 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 66 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 67 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 68 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 69 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 70 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 71 * SUCH DAMAGE. 72 * 73 * XScale core 3 assembly functions for CPU / MMU / TLB specific operations 74 */ 75 76#include <machine/armreg.h> 77#include <machine/asm.h> 78__FBSDID("$FreeBSD: stable/11/sys/arm/arm/cpufunc_asm_xscale_c3.S 331890 2018-04-02 22:02:49Z gonzo $"); 79 80/* 81 * Size of the XScale core D-cache. 82 */ 83#define DCACHE_SIZE 0x00008000 84 85/* 86 * CPWAIT -- Canonical method to wait for CP15 update. 87 * From: Intel 80200 manual, section 2.3.3. 88 * 89 * NOTE: Clobbers the specified temp reg. 90 */ 91#define CPWAIT_BRANCH \ 92 sub pc, pc, #4 93 94#define CPWAIT(tmp) \ 95 mrc p15, 0, tmp, c2, c0, 0 /* arbitrary read of CP15 */ ;\ 96 mov tmp, tmp /* wait for it to complete */ ;\ 97 CPWAIT_BRANCH /* branch to next insn */ 98 99#define CPWAIT_AND_RETURN_SHIFTER lsr #32 100 101#define CPWAIT_AND_RETURN(tmp) \ 102 mrc p15, 0, tmp, c2, c0, 0 /* arbitrary read of CP15 */ ;\ 103 /* Wait for it to complete and branch to the return address */ \ 104 sub pc, lr, tmp, CPWAIT_AND_RETURN_SHIFTER 105 106#define ARM_USE_L2_CACHE 107 108#define L2_CACHE_SIZE 0x80000 109#define L2_CACHE_WAYS 8 110#define L2_CACHE_LINE_SIZE 32 111#define L2_CACHE_SETS (L2_CACHE_SIZE / \ 112 (L2_CACHE_WAYS * L2_CACHE_LINE_SIZE)) 113 114#define L1_DCACHE_SIZE 32 * 1024 115#define L1_DCACHE_WAYS 4 116#define L1_DCACHE_LINE_SIZE 32 117#define L1_DCACHE_SETS (L1_DCACHE_SIZE / \ 118 (L1_DCACHE_WAYS * L1_DCACHE_LINE_SIZE)) 119#ifdef CACHE_CLEAN_BLOCK_INTR 120#define XSCALE_CACHE_CLEAN_BLOCK \ 121 stmfd sp!, {r4} ; \ 122 mrs r4, cpsr ; \ 123 orr r0, r4, #(PSR_I | PSR_F) ; \ 124 msr cpsr_fsxc, r0 125 126#define XSCALE_CACHE_CLEAN_UNBLOCK \ 127 msr cpsr_fsxc, r4 ; \ 128 ldmfd sp!, {r4} 129#else 130#define XSCALE_CACHE_CLEAN_BLOCK 131#define XSCALE_CACHE_CLEAN_UNBLOCK 132#endif /* CACHE_CLEAN_BLOCK_INTR */ 133 134 135ENTRY_NP(xscalec3_cache_syncI) 136EENTRY_NP(xscalec3_cache_purgeID) 137 mcr p15, 0, r0, c7, c5, 0 /* flush I cache (D cleaned below) */ 138EENTRY_NP(xscalec3_cache_cleanID) 139EENTRY_NP(xscalec3_cache_purgeD) 140EENTRY(xscalec3_cache_cleanD) 141 142 XSCALE_CACHE_CLEAN_BLOCK 143 mov r0, #0 1441: 145 mov r1, r0, asl #30 146 mov r2, #0 1472: 148 orr r3, r1, r2, asl #5 149 mcr p15, 0, r3, c7, c14, 2 /* clean and invalidate */ 150 add r2, r2, #1 151 cmp r2, #L1_DCACHE_SETS 152 bne 2b 153 add r0, r0, #1 154 cmp r0, #4 155 bne 1b 156 CPWAIT(r0) 157 XSCALE_CACHE_CLEAN_UNBLOCK 158 mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ 159 160 RET 161EEND(xscalec3_cache_purgeID) 162EEND(xscalec3_cache_cleanID) 163EEND(xscalec3_cache_purgeD) 164EEND(xscalec3_cache_cleanD) 165END(xscalec3_cache_syncI) 166 167ENTRY(xscalec3_cache_purgeID_rng) 168 169 cmp r1, #0x4000 170 bcs _C_LABEL(xscalec3_cache_cleanID) 171 and r2, r0, #0x1f 172 add r1, r1, r2 173 bic r0, r0, #0x1f 174 1751: mcr p15, 0, r0, c7, c14, 1 /* clean/invalidate L1 D cache entry */ 176 nop 177 mcr p15, 0, r0, c7, c5, 1 /* flush I cache single entry */ 178 add r0, r0, #32 179 subs r1, r1, #32 180 bhi 1b 181 182 CPWAIT(r0) 183 184 mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ 185 186 CPWAIT_AND_RETURN(r0) 187END(xscalec3_cache_purgeID_rng) 188 189ENTRY(xscalec3_cache_syncI_rng) 190 cmp r1, #0x4000 191 bcs _C_LABEL(xscalec3_cache_syncI) 192 193 and r2, r0, #0x1f 194 add r1, r1, r2 195 bic r0, r0, #0x1f 196 1971: mcr p15, 0, r0, c7, c10, 1 /* clean D cache entry */ 198 mcr p15, 0, r0, c7, c5, 1 /* flush I cache single entry */ 199 add r0, r0, #32 200 subs r1, r1, #32 201 bhi 1b 202 203 CPWAIT(r0) 204 205 mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ 206 207 CPWAIT_AND_RETURN(r0) 208END(xscalec3_cache_syncI_rng) 209 210ENTRY(xscalec3_cache_purgeD_rng) 211 212 cmp r1, #0x4000 213 bcs _C_LABEL(xscalec3_cache_cleanID) 214 and r2, r0, #0x1f 215 add r1, r1, r2 216 bic r0, r0, #0x1f 217 2181: mcr p15, 0, r0, c7, c14, 1 /* Clean and invalidate D cache entry */ 219 add r0, r0, #32 220 subs r1, r1, #32 221 bhi 1b 222 223 CPWAIT(r0) 224 225 mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ 226 227 CPWAIT_AND_RETURN(r0) 228END(xscalec3_cache_purgeD_rng) 229 230ENTRY(xscalec3_cache_cleanID_rng) 231EENTRY(xscalec3_cache_cleanD_rng) 232 233 cmp r1, #0x4000 234 bcs _C_LABEL(xscalec3_cache_cleanID) 235 and r2, r0, #0x1f 236 add r1, r1, r2 237 bic r0, r0, #0x1f 238 2391: mcr p15, 0, r0, c7, c10, 1 /* clean L1 D cache entry */ 240 nop 241 add r0, r0, #32 242 subs r1, r1, #32 243 bhi 1b 244 245 CPWAIT(r0) 246 247 mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ 248 249 CPWAIT_AND_RETURN(r0) 250EEND(xscalec3_cache_cleanD_rng) 251END(xscalec3_cache_cleanID_rng) 252 253ENTRY(xscalec3_l2cache_purge) 254 /* Clean-up the L2 cache */ 255 mcr p15, 0, r0, c7, c10, 5 /* Data memory barrier */ 256 mov r0, #0 2571: 258 mov r1, r0, asl #29 259 mov r2, #0 2602: 261 orr r3, r1, r2, asl #5 262 mcr p15, 1, r3, c7, c15, 2 263 add r2, r2, #1 264 cmp r2, #L2_CACHE_SETS 265 bne 2b 266 add r0, r0, #1 267 cmp r0, #8 268 bne 1b 269 mcr p15, 0, r0, c7, c10, 4 @ data write barrier 270 271 CPWAIT(r0) 272 mcr p15, 0, r0, c7, c10, 5 /* Data memory barrier */ 273 RET 274END(xscalec3_l2cache_purge) 275 276ENTRY(xscalec3_l2cache_clean_rng) 277 mcr p15, 0, r0, c7, c10, 5 /* Data memory barrier */ 278 279 and r2, r0, #0x1f 280 add r1, r1, r2 281 bic r0, r0, #0x1f 282 2831: mcr p15, 1, r0, c7, c11, 1 /* Clean L2 D cache entry */ 284 add r0, r0, #32 285 subs r1, r1, #32 286 bhi 1b 287 288 289 CPWAIT(r0) 290 291 mcr p15, 0, r0, c7, c10, 4 @ data write barrier 292 mcr p15, 0, r0, c7, c10, 5 293 294 CPWAIT_AND_RETURN(r0) 295END(xscalec3_l2cache_clean_rng) 296 297ENTRY(xscalec3_l2cache_purge_rng) 298 299 mcr p15, 0, r0, c7, c10, 5 /* Data memory barrier */ 300 301 and r2, r0, #0x1f 302 add r1, r1, r2 303 bic r0, r0, #0x1f 304 3051: mcr p15, 1, r0, c7, c11, 1 /* Clean L2 D cache entry */ 306 mcr p15, 1, r0, c7, c7, 1 /* Invalidate L2 D cache entry */ 307 add r0, r0, #32 308 subs r1, r1, #32 309 bhi 1b 310 311 mcr p15, 0, r0, c7, c10, 4 @ data write barrier 312 mcr p15, 0, r0, c7, c10, 5 313 314 CPWAIT_AND_RETURN(r0) 315END(xscalec3_l2cache_purge_rng) 316 317ENTRY(xscalec3_l2cache_flush_rng) 318 mcr p15, 0, r0, c7, c10, 5 /* Data memory barrier */ 319 320 and r2, r0, #0x1f 321 add r1, r1, r2 322 bic r0, r0, #0x1f 323 3241: mcr p15, 1, r0, c7, c7, 1 /* Invalidate L2 cache line */ 325 add r0, r0, #32 326 subs r1, r1, #32 327 bhi 1b 328 mcr p15, 0, r0, c7, c10, 4 @ data write barrier 329 mcr p15, 0, r0, c7, c10, 5 330 CPWAIT_AND_RETURN(r0) 331END(xscalec3_l2cache_flush_rng) 332 333/* 334 * Functions to set the MMU Translation Table Base register 335 * 336 * We need to clean and flush the cache as it uses virtual 337 * addresses that are about to change. 338 */ 339ENTRY(xscalec3_setttb) 340#ifdef CACHE_CLEAN_BLOCK_INTR 341 mrs r3, cpsr 342 orr r1, r3, #(PSR_I | PSR_F) 343 msr cpsr_fsxc, r1 344#endif 345 stmfd sp!, {r0-r3, lr} 346 bl _C_LABEL(xscalec3_cache_cleanID) 347 mcr p15, 0, r0, c7, c5, 0 /* invalidate I$ and BTB */ 348 mcr p15, 0, r0, c7, c10, 4 /* drain write and fill buffer */ 349 350 CPWAIT(r0) 351 352 ldmfd sp!, {r0-r3, lr} 353 354#ifdef ARM_USE_L2_CACHE 355 orr r0, r0, #0x18 /* cache the page table in L2 */ 356#endif 357 /* Write the TTB */ 358 mcr p15, 0, r0, c2, c0, 0 359 360 /* If we have updated the TTB we must flush the TLB */ 361 mcr p15, 0, r0, c8, c7, 0 /* invalidate I+D TLB */ 362 363 CPWAIT(r0) 364 365#ifdef CACHE_CLEAN_BLOCK_INTR 366 msr cpsr_fsxc, r3 367#endif 368 RET 369END(xscalec3_setttb) 370 371/* 372 * Context switch. 373 * 374 * These is the CPU-specific parts of the context switcher cpu_switch() 375 * These functions actually perform the TTB reload. 376 * 377 * NOTE: Special calling convention 378 * r1, r4-r13 must be preserved 379 */ 380ENTRY(xscalec3_context_switch) 381 /* 382 * CF_CACHE_PURGE_ID will *ALWAYS* be called prior to this. 383 * Thus the data cache will contain only kernel data and the 384 * instruction cache will contain only kernel code, and all 385 * kernel mappings are shared by all processes. 386 */ 387#ifdef ARM_USE_L2_CACHE 388 orr r0, r0, #0x18 /* Cache the page table in L2 */ 389#endif 390 /* Write the TTB */ 391 mcr p15, 0, r0, c2, c0, 0 392 393 /* If we have updated the TTB we must flush the TLB */ 394 mcr p15, 0, r0, c8, c7, 0 /* flush the I+D tlb */ 395 396 CPWAIT_AND_RETURN(r0) 397END(xscalec3_context_switch) 398 399