cpufunc_asm_xscale_c3.S revision 275767
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/asm.h> 77__FBSDID("$FreeBSD: stable/10/sys/arm/arm/cpufunc_asm_xscale_c3.S 275767 2014-12-14 16:28:53Z andrew $"); 78 79/* 80 * Size of the XScale core D-cache. 81 */ 82#define DCACHE_SIZE 0x00008000 83 84.Lblock_userspace_access: 85 .word _C_LABEL(block_userspace_access) 86 87/* 88 * CPWAIT -- Canonical method to wait for CP15 update. 89 * From: Intel 80200 manual, section 2.3.3. 90 * 91 * NOTE: Clobbers the specified temp reg. 92 */ 93#define CPWAIT_BRANCH \ 94 sub pc, pc, #4 95 96#define CPWAIT(tmp) \ 97 mrc p15, 0, tmp, c2, c0, 0 /* arbitrary read of CP15 */ ;\ 98 mov tmp, tmp /* wait for it to complete */ ;\ 99 CPWAIT_BRANCH /* branch to next insn */ 100 101#define CPWAIT_AND_RETURN_SHIFTER lsr #32 102 103#define CPWAIT_AND_RETURN(tmp) \ 104 mrc p15, 0, tmp, c2, c0, 0 /* arbitrary read of CP15 */ ;\ 105 /* Wait for it to complete and branch to the return address */ \ 106 sub pc, lr, tmp, CPWAIT_AND_RETURN_SHIFTER 107 108#define ARM_USE_L2_CACHE 109 110#define L2_CACHE_SIZE 0x80000 111#define L2_CACHE_WAYS 8 112#define L2_CACHE_LINE_SIZE 32 113#define L2_CACHE_SETS (L2_CACHE_SIZE / \ 114 (L2_CACHE_WAYS * L2_CACHE_LINE_SIZE)) 115 116#define L1_DCACHE_SIZE 32 * 1024 117#define L1_DCACHE_WAYS 4 118#define L1_DCACHE_LINE_SIZE 32 119#define L1_DCACHE_SETS (L1_DCACHE_SIZE / \ 120 (L1_DCACHE_WAYS * L1_DCACHE_LINE_SIZE)) 121#ifdef CACHE_CLEAN_BLOCK_INTR 122#define XSCALE_CACHE_CLEAN_BLOCK \ 123 stmfd sp!, {r4} ; \ 124 mrs r4, cpsr ; \ 125 orr r0, r4, #(I32_bit | F32_bit) ; \ 126 msr cpsr_fsxc, r0 127 128#define XSCALE_CACHE_CLEAN_UNBLOCK \ 129 msr cpsr_fsxc, r4 ; \ 130 ldmfd sp!, {r4} 131#else 132#define XSCALE_CACHE_CLEAN_BLOCK \ 133 stmfd sp!, {r4} ; \ 134 ldr r4, .Lblock_userspace_access ; \ 135 ldr ip, [r4] ; \ 136 orr r0, ip, #1 ; \ 137 str r0, [r4] 138 139#define XSCALE_CACHE_CLEAN_UNBLOCK \ 140 str ip, [r3] ; \ 141 ldmfd sp!, {r4} 142#endif /* CACHE_CLEAN_BLOCK_INTR */ 143 144 145ENTRY_NP(xscalec3_cache_syncI) 146EENTRY_NP(xscalec3_cache_purgeID) 147 mcr p15, 0, r0, c7, c5, 0 /* flush I cache (D cleaned below) */ 148EENTRY_NP(xscalec3_cache_cleanID) 149EENTRY_NP(xscalec3_cache_purgeD) 150EENTRY(xscalec3_cache_cleanD) 151 152 XSCALE_CACHE_CLEAN_BLOCK 153 mov r0, #0 1541: 155 mov r1, r0, asl #30 156 mov r2, #0 1572: 158 orr r3, r1, r2, asl #5 159 mcr p15, 0, r3, c7, c14, 2 /* clean and invalidate */ 160 add r2, r2, #1 161 cmp r2, #L1_DCACHE_SETS 162 bne 2b 163 add r0, r0, #1 164 cmp r0, #4 165 bne 1b 166 CPWAIT(r0) 167 XSCALE_CACHE_CLEAN_UNBLOCK 168 mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ 169 170 RET 171EEND(xscalec3_cache_purgeID) 172EEND(xscalec3_cache_cleanID) 173EEND(xscalec3_cache_purgeD) 174EEND(xscalec3_cache_cleanD) 175END(xscalec3_cache_syncI) 176 177ENTRY(xscalec3_cache_purgeID_rng) 178 179 cmp r1, #0x4000 180 bcs _C_LABEL(xscalec3_cache_cleanID) 181 and r2, r0, #0x1f 182 add r1, r1, r2 183 bic r0, r0, #0x1f 184 1851: mcr p15, 0, r0, c7, c14, 1 /* clean/invalidate L1 D cache entry */ 186 nop 187 mcr p15, 0, r0, c7, c5, 1 /* flush I cache single entry */ 188 add r0, r0, #32 189 subs r1, r1, #32 190 bhi 1b 191 192 CPWAIT(r0) 193 194 mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ 195 196 CPWAIT_AND_RETURN(r0) 197END(xscalec3_cache_purgeID_rng) 198 199ENTRY(xscalec3_cache_syncI_rng) 200 cmp r1, #0x4000 201 bcs _C_LABEL(xscalec3_cache_syncI) 202 203 and r2, r0, #0x1f 204 add r1, r1, r2 205 bic r0, r0, #0x1f 206 2071: mcr p15, 0, r0, c7, c10, 1 /* clean D cache entry */ 208 mcr p15, 0, r0, c7, c5, 1 /* flush I cache single entry */ 209 add r0, r0, #32 210 subs r1, r1, #32 211 bhi 1b 212 213 CPWAIT(r0) 214 215 mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ 216 217 CPWAIT_AND_RETURN(r0) 218END(xscalec3_cache_syncI_rng) 219 220ENTRY(xscalec3_cache_purgeD_rng) 221 222 cmp r1, #0x4000 223 bcs _C_LABEL(xscalec3_cache_cleanID) 224 and r2, r0, #0x1f 225 add r1, r1, r2 226 bic r0, r0, #0x1f 227 2281: mcr p15, 0, r0, c7, c14, 1 /* Clean and invalidate D cache entry */ 229 add r0, r0, #32 230 subs r1, r1, #32 231 bhi 1b 232 233 CPWAIT(r0) 234 235 mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ 236 237 CPWAIT_AND_RETURN(r0) 238END(xscalec3_cache_purgeD_rng) 239 240ENTRY(xscalec3_cache_cleanID_rng) 241EENTRY(xscalec3_cache_cleanD_rng) 242 243 cmp r1, #0x4000 244 bcs _C_LABEL(xscalec3_cache_cleanID) 245 and r2, r0, #0x1f 246 add r1, r1, r2 247 bic r0, r0, #0x1f 248 2491: mcr p15, 0, r0, c7, c10, 1 /* clean L1 D cache entry */ 250 nop 251 add r0, r0, #32 252 subs r1, r1, #32 253 bhi 1b 254 255 CPWAIT(r0) 256 257 mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ 258 259 CPWAIT_AND_RETURN(r0) 260EEND(xscalec3_cache_cleanD_rng) 261END(xscalec3_cache_cleanID_rng) 262 263ENTRY(xscalec3_l2cache_purge) 264 /* Clean-up the L2 cache */ 265 mcr p15, 0, r0, c7, c10, 5 /* Data memory barrier */ 266 mov r0, #0 2671: 268 mov r1, r0, asl #29 269 mov r2, #0 2702: 271 orr r3, r1, r2, asl #5 272 mcr p15, 1, r3, c7, c15, 2 273 add r2, r2, #1 274 cmp r2, #L2_CACHE_SETS 275 bne 2b 276 add r0, r0, #1 277 cmp r0, #8 278 bne 1b 279 mcr p15, 0, r0, c7, c10, 4 @ data write barrier 280 281 CPWAIT(r0) 282 mcr p15, 0, r0, c7, c10, 5 /* Data memory barrier */ 283 RET 284END(xscalec3_l2cache_purge) 285 286ENTRY(xscalec3_l2cache_clean_rng) 287 mcr p15, 0, r0, c7, c10, 5 /* Data memory barrier */ 288 289 and r2, r0, #0x1f 290 add r1, r1, r2 291 bic r0, r0, #0x1f 292 2931: mcr p15, 1, r0, c7, c11, 1 /* Clean L2 D cache entry */ 294 add r0, r0, #32 295 subs r1, r1, #32 296 bhi 1b 297 298 299 CPWAIT(r0) 300 301 mcr p15, 0, r0, c7, c10, 4 @ data write barrier 302 mcr p15, 0, r0, c7, c10, 5 303 304 CPWAIT_AND_RETURN(r0) 305END(xscalec3_l2cache_clean_rng) 306 307ENTRY(xscalec3_l2cache_purge_rng) 308 309 mcr p15, 0, r0, c7, c10, 5 /* Data memory barrier */ 310 311 and r2, r0, #0x1f 312 add r1, r1, r2 313 bic r0, r0, #0x1f 314 3151: mcr p15, 1, r0, c7, c11, 1 /* Clean L2 D cache entry */ 316 mcr p15, 1, r0, c7, c7, 1 /* Invalidate L2 D cache entry */ 317 add r0, r0, #32 318 subs r1, r1, #32 319 bhi 1b 320 321 mcr p15, 0, r0, c7, c10, 4 @ data write barrier 322 mcr p15, 0, r0, c7, c10, 5 323 324 CPWAIT_AND_RETURN(r0) 325END(xscalec3_l2cache_purge_rng) 326 327ENTRY(xscalec3_l2cache_flush_rng) 328 mcr p15, 0, r0, c7, c10, 5 /* Data memory barrier */ 329 330 and r2, r0, #0x1f 331 add r1, r1, r2 332 bic r0, r0, #0x1f 333 3341: mcr p15, 1, r0, c7, c7, 1 /* Invalidate L2 cache line */ 335 add r0, r0, #32 336 subs r1, r1, #32 337 bhi 1b 338 mcr p15, 0, r0, c7, c10, 4 @ data write barrier 339 mcr p15, 0, r0, c7, c10, 5 340 CPWAIT_AND_RETURN(r0) 341END(xscalec3_l2cache_flush_rng) 342 343/* 344 * Functions to set the MMU Translation Table Base register 345 * 346 * We need to clean and flush the cache as it uses virtual 347 * addresses that are about to change. 348 */ 349ENTRY(xscalec3_setttb) 350#ifdef CACHE_CLEAN_BLOCK_INTR 351 mrs r3, cpsr 352 orr r1, r3, #(I32_bit | F32_bit) 353 msr cpsr_fsxc, r1 354#else 355 ldr r3, .Lblock_userspace_access 356 ldr r2, [r3] 357 orr r1, r2, #1 358 str r1, [r3] 359#endif 360 stmfd sp!, {r0-r3, lr} 361 bl _C_LABEL(xscalec3_cache_cleanID) 362 mcr p15, 0, r0, c7, c5, 0 /* invalidate I$ and BTB */ 363 mcr p15, 0, r0, c7, c10, 4 /* drain write and fill buffer */ 364 365 CPWAIT(r0) 366 367 ldmfd sp!, {r0-r3, lr} 368 369#ifdef ARM_USE_L2_CACHE 370 orr r0, r0, #0x18 /* cache the page table in L2 */ 371#endif 372 /* Write the TTB */ 373 mcr p15, 0, r0, c2, c0, 0 374 375 /* If we have updated the TTB we must flush the TLB */ 376 mcr p15, 0, r0, c8, c7, 0 /* invalidate I+D TLB */ 377 378 CPWAIT(r0) 379 380#ifdef CACHE_CLEAN_BLOCK_INTR 381 msr cpsr_fsxc, r3 382#else 383 str r2, [r3] 384#endif 385 RET 386END(xscalec3_setttb) 387 388/* 389 * Context switch. 390 * 391 * These is the CPU-specific parts of the context switcher cpu_switch() 392 * These functions actually perform the TTB reload. 393 * 394 * NOTE: Special calling convention 395 * r1, r4-r13 must be preserved 396 */ 397ENTRY(xscalec3_context_switch) 398 /* 399 * CF_CACHE_PURGE_ID will *ALWAYS* be called prior to this. 400 * Thus the data cache will contain only kernel data and the 401 * instruction cache will contain only kernel code, and all 402 * kernel mappings are shared by all processes. 403 */ 404#ifdef ARM_USE_L2_CACHE 405 orr r0, r0, #0x18 /* Cache the page table in L2 */ 406#endif 407 /* Write the TTB */ 408 mcr p15, 0, r0, c2, c0, 0 409 410 /* If we have updated the TTB we must flush the TLB */ 411 mcr p15, 0, r0, c8, c7, 0 /* flush the I+D tlb */ 412 413 CPWAIT_AND_RETURN(r0) 414END(xscalec3_context_switch) 415 416