1183835Sraj/*- 2183835Sraj * Copyright (C) 2008 MARVELL INTERNATIONAL LTD. 3183835Sraj * All rights reserved. 4183835Sraj * 5183835Sraj * Developed by Semihalf. 6183835Sraj * 7183835Sraj * Redistribution and use in source and binary forms, with or without 8183835Sraj * modification, are permitted provided that the following conditions 9183835Sraj * are met: 10183835Sraj * 1. Redistributions of source code must retain the above copyright 11183835Sraj * notice, this list of conditions and the following disclaimer. 12183835Sraj * 2. Redistributions in binary form must reproduce the above copyright 13183835Sraj * notice, this list of conditions and the following disclaimer in the 14183835Sraj * documentation and/or other materials provided with the distribution. 15183835Sraj * 3. Neither the name of MARVELL nor the names of contributors 16183835Sraj * may be used to endorse or promote products derived from this software 17183835Sraj * without specific prior written permission. 18183835Sraj * 19183835Sraj * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20183835Sraj * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21183835Sraj * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22183835Sraj * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 23183835Sraj * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24183835Sraj * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25183835Sraj * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26183835Sraj * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27183835Sraj * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28183835Sraj * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29183835Sraj * SUCH DAMAGE. 30183835Sraj */ 31183835Sraj 32271398Sandrew#include <machine/armreg.h> 33183835Sraj#include <machine/asm.h> 34183835Sraj__FBSDID("$FreeBSD: releng/11.0/sys/arm/arm/cpufunc_asm_sheeva.S 275417 2014-12-02 18:35:34Z andrew $"); 35183835Sraj 36183835Sraj#include <machine/param.h> 37183835Sraj 38186933Sraj.Lsheeva_cache_line_size: 39183835Sraj .word _C_LABEL(arm_pdcache_line_size) 40186933Sraj.Lsheeva_asm_page_mask: 41183835Sraj .word _C_LABEL(PAGE_MASK) 42183835Sraj 43186933SrajENTRY(sheeva_setttb) 44183835Sraj /* Disable irqs */ 45183835Sraj mrs r2, cpsr 46271398Sandrew orr r3, r2, #PSR_I | PSR_F 47183835Sraj msr cpsr_c, r3 48183835Sraj 49183835Sraj mov r1, #0 50183835Sraj mcr p15, 0, r1, c7, c5, 0 /* Invalidate ICache */ 51275417Sandrew1: mrc p15, 0, APSR_nzcv, c7, c14, 3 /* Test, clean and invalidate DCache */ 52183835Sraj bne 1b /* More to do? */ 53183835Sraj 54183835Sraj mcr p15, 1, r1, c15, c9, 0 /* Clean L2 */ 55183835Sraj mcr p15, 1, r1, c15, c11, 0 /* Invalidate L2 */ 56183835Sraj 57183835Sraj /* Reenable irqs */ 58183835Sraj msr cpsr_c, r2 59183835Sraj 60183835Sraj mcr p15, 0, r1, c7, c10, 4 /* drain the write buffer */ 61183835Sraj 62183835Sraj mcr p15, 0, r0, c2, c0, 0 /* load new TTB */ 63183835Sraj 64183835Sraj mcr p15, 0, r0, c8, c7, 0 /* invalidate I+D TLBs */ 65183835Sraj RET 66248361SandrewEND(sheeva_setttb) 67183835Sraj 68186933SrajENTRY(sheeva_dcache_wbinv_range) 69183835Sraj str lr, [sp, #-4]! 70183835Sraj mrs lr, cpsr 71183835Sraj /* Start with cache line aligned address */ 72186933Sraj ldr ip, .Lsheeva_cache_line_size 73183835Sraj ldr ip, [ip] 74183835Sraj sub ip, ip, #1 75183835Sraj and r2, r0, ip 76183835Sraj add r1, r1, r2 77183835Sraj add r1, r1, ip 78183835Sraj bics r1, r1, ip 79183835Sraj bics r0, r0, ip 80183835Sraj 81186933Sraj ldr ip, .Lsheeva_asm_page_mask 82183835Sraj and r2, r0, ip 83183835Sraj rsb r2, r2, #PAGE_SIZE 84183835Sraj cmp r1, r2 85183835Sraj movcc ip, r1 86183835Sraj movcs ip, r2 87183835Sraj1: 88183835Sraj add r3, r0, ip 89183835Sraj sub r2, r3, #1 90183835Sraj /* Disable irqs */ 91271398Sandrew orr r3, lr, #PSR_I | PSR_F 92183835Sraj msr cpsr_c, r3 93183835Sraj mcr p15, 5, r0, c15, c15, 0 /* Clean and inv zone start address */ 94183835Sraj mcr p15, 5, r2, c15, c15, 1 /* Clean and inv zone end address */ 95183835Sraj /* Enable irqs */ 96183835Sraj msr cpsr_c, lr 97183835Sraj 98183835Sraj add r0, r0, ip 99183835Sraj sub r1, r1, ip 100183835Sraj cmp r1, #PAGE_SIZE 101183835Sraj movcc ip, r1 102183835Sraj movcs ip, #PAGE_SIZE 103183835Sraj cmp r1, #0 104183835Sraj bne 1b 105183835Sraj mov r0, #0 106183835Sraj mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */ 107183835Sraj ldr lr, [sp], #4 108183835Sraj RET 109248361SandrewEND(sheeva_dcache_wbinv_range) 110183835Sraj 111186933SrajENTRY(sheeva_idcache_wbinv_range) 112183835Sraj str lr, [sp, #-4]! 113183835Sraj mrs lr, cpsr 114183835Sraj /* Start with cache line aligned address */ 115186933Sraj ldr ip, .Lsheeva_cache_line_size 116183835Sraj ldr ip, [ip] 117183835Sraj sub ip, ip, #1 118183835Sraj and r2, r0, ip 119183835Sraj add r1, r1, r2 120183835Sraj add r1, r1, ip 121183835Sraj bics r1, r1, ip 122183835Sraj bics r0, r0, ip 123183835Sraj 124186933Sraj ldr ip, .Lsheeva_asm_page_mask 125183835Sraj and r2, r0, ip 126183835Sraj rsb r2, r2, #PAGE_SIZE 127183835Sraj cmp r1, r2 128183835Sraj movcc ip, r1 129183835Sraj movcs ip, r2 130183835Sraj1: 131183835Sraj add r3, r0, ip 132183835Sraj sub r2, r3, #1 133183835Sraj /* Disable irqs */ 134271398Sandrew orr r3, lr, #PSR_I | PSR_F 135183835Sraj msr cpsr_c, r3 136183835Sraj mcr p15, 5, r0, c15, c15, 0 /* Clean and inv zone start address */ 137183835Sraj mcr p15, 5, r2, c15, c15, 1 /* Clean and inv zone end address */ 138183835Sraj /* Enable irqs */ 139183835Sraj msr cpsr_c, lr 140183835Sraj 141183835Sraj /* Invalidate and clean icache line by line */ 142186933Sraj ldr r3, .Lsheeva_cache_line_size 143183835Sraj ldr r3, [r3] 144183835Sraj2: 145183835Sraj mcr p15, 0, r0, c7, c5, 1 146183835Sraj add r0, r0, r3 147183835Sraj cmp r2, r0 148183835Sraj bhi 2b 149183835Sraj 150183835Sraj add r0, r2, #1 151183835Sraj sub r1, r1, ip 152183835Sraj cmp r1, #PAGE_SIZE 153183835Sraj movcc ip, r1 154183835Sraj movcs ip, #PAGE_SIZE 155183835Sraj cmp r1, #0 156183835Sraj bne 1b 157183835Sraj mov r0, #0 158183835Sraj mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */ 159183835Sraj ldr lr, [sp], #4 160183835Sraj RET 161248361SandrewEND(sheeva_idcache_wbinv_range) 162183835Sraj 163186933SrajENTRY(sheeva_dcache_inv_range) 164183835Sraj str lr, [sp, #-4]! 165183835Sraj mrs lr, cpsr 166183835Sraj /* Start with cache line aligned address */ 167186933Sraj ldr ip, .Lsheeva_cache_line_size 168183835Sraj ldr ip, [ip] 169183835Sraj sub ip, ip, #1 170183835Sraj and r2, r0, ip 171183835Sraj add r1, r1, r2 172183835Sraj add r1, r1, ip 173183835Sraj bics r1, r1, ip 174183835Sraj bics r0, r0, ip 175183835Sraj 176186933Sraj ldr ip, .Lsheeva_asm_page_mask 177183835Sraj and r2, r0, ip 178183835Sraj rsb r2, r2, #PAGE_SIZE 179183835Sraj cmp r1, r2 180183835Sraj movcc ip, r1 181183835Sraj movcs ip, r2 182183835Sraj1: 183183835Sraj add r3, r0, ip 184183835Sraj sub r2, r3, #1 185183835Sraj /* Disable irqs */ 186271398Sandrew orr r3, lr, #PSR_I | PSR_F 187183835Sraj msr cpsr_c, r3 188183835Sraj mcr p15, 5, r0, c15, c14, 0 /* Inv zone start address */ 189183835Sraj mcr p15, 5, r2, c15, c14, 1 /* Inv zone end address */ 190183835Sraj /* Enable irqs */ 191183835Sraj msr cpsr_c, lr 192183835Sraj 193183835Sraj add r0, r0, ip 194183835Sraj sub r1, r1, ip 195183835Sraj cmp r1, #PAGE_SIZE 196183835Sraj movcc ip, r1 197183835Sraj movcs ip, #PAGE_SIZE 198183835Sraj cmp r1, #0 199183835Sraj bne 1b 200183835Sraj mov r0, #0 201183835Sraj mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */ 202183835Sraj ldr lr, [sp], #4 203183835Sraj RET 204248361SandrewEND(sheeva_dcache_inv_range) 205183835Sraj 206186933SrajENTRY(sheeva_dcache_wb_range) 207183835Sraj str lr, [sp, #-4]! 208183835Sraj mrs lr, cpsr 209183835Sraj /* Start with cache line aligned address */ 210186933Sraj ldr ip, .Lsheeva_cache_line_size 211183835Sraj ldr ip, [ip] 212183835Sraj sub ip, ip, #1 213183835Sraj and r2, r0, ip 214183835Sraj add r1, r1, r2 215183835Sraj add r1, r1, ip 216183835Sraj bics r1, r1, ip 217183835Sraj bics r0, r0, ip 218183835Sraj 219186933Sraj ldr ip, .Lsheeva_asm_page_mask 220183835Sraj and r2, r0, ip 221183835Sraj rsb r2, r2, #PAGE_SIZE 222183835Sraj cmp r1, r2 223183835Sraj movcc ip, r1 224183835Sraj movcs ip, r2 225183835Sraj1: 226183835Sraj add r3, r0, ip 227183835Sraj sub r2, r3, #1 228183835Sraj /* Disable irqs */ 229271398Sandrew orr r3, lr, #PSR_I | PSR_F 230183835Sraj msr cpsr_c, r3 231183835Sraj mcr p15, 5, r0, c15, c13, 0 /* Clean zone start address */ 232183835Sraj mcr p15, 5, r2, c15, c13, 1 /* Clean zone end address */ 233183835Sraj /* Enable irqs */ 234183835Sraj msr cpsr_c, lr 235183835Sraj 236183835Sraj add r0, r0, ip 237183835Sraj sub r1, r1, ip 238183835Sraj cmp r1, #PAGE_SIZE 239183835Sraj movcc ip, r1 240183835Sraj movcs ip, #PAGE_SIZE 241183835Sraj cmp r1, #0 242183835Sraj bne 1b 243183835Sraj mov r0, #0 244183835Sraj mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */ 245183835Sraj ldr lr, [sp], #4 246183835Sraj RET 247248361SandrewEND(sheeva_dcache_wb_range) 248183835Sraj 249186933SrajENTRY(sheeva_l2cache_wbinv_range) 250183835Sraj str lr, [sp, #-4]! 251183835Sraj mrs lr, cpsr 252183835Sraj /* Start with cache line aligned address */ 253186933Sraj ldr ip, .Lsheeva_cache_line_size 254183835Sraj ldr ip, [ip] 255183835Sraj sub ip, ip, #1 256183835Sraj and r2, r0, ip 257183835Sraj add r1, r1, r2 258183835Sraj add r1, r1, ip 259183835Sraj bics r1, r1, ip 260183835Sraj bics r0, r0, ip 261183835Sraj 262186933Sraj ldr ip, .Lsheeva_asm_page_mask 263183835Sraj and r2, r0, ip 264183835Sraj rsb r2, r2, #PAGE_SIZE 265183835Sraj cmp r1, r2 266183835Sraj movcc ip, r1 267183835Sraj movcs ip, r2 268183835Sraj1: 269183835Sraj add r3, r0, ip 270183835Sraj sub r2, r3, #1 271183835Sraj /* Disable irqs */ 272271398Sandrew orr r3, lr, #PSR_I | PSR_F 273183835Sraj msr cpsr_c, r3 274183835Sraj mcr p15, 1, r0, c15, c9, 4 /* Clean L2 zone start address */ 275183835Sraj mcr p15, 1, r2, c15, c9, 5 /* Clean L2 zone end address */ 276183835Sraj mcr p15, 1, r0, c15, c11, 4 /* Inv L2 zone start address */ 277183835Sraj mcr p15, 1, r2, c15, c11, 5 /* Inv L2 zone end address */ 278183835Sraj /* Enable irqs */ 279183835Sraj msr cpsr_c, lr 280183835Sraj 281183835Sraj add r0, r0, ip 282183835Sraj sub r1, r1, ip 283183835Sraj cmp r1, #PAGE_SIZE 284183835Sraj movcc ip, r1 285183835Sraj movcs ip, #PAGE_SIZE 286183835Sraj cmp r1, #0 287183835Sraj bne 1b 288183835Sraj mov r0, #0 289183835Sraj mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */ 290183835Sraj ldr lr, [sp], #4 291183835Sraj RET 292248361SandrewEND(sheeva_l2cache_wbinv_range) 293183835Sraj 294186933SrajENTRY(sheeva_l2cache_inv_range) 295183835Sraj str lr, [sp, #-4]! 296183835Sraj mrs lr, cpsr 297183835Sraj /* Start with cache line aligned address */ 298186933Sraj ldr ip, .Lsheeva_cache_line_size 299183835Sraj ldr ip, [ip] 300183835Sraj sub ip, ip, #1 301183835Sraj and r2, r0, ip 302183835Sraj add r1, r1, r2 303183835Sraj add r1, r1, ip 304183835Sraj bics r1, r1, ip 305183835Sraj bics r0, r0, ip 306183835Sraj 307186933Sraj ldr ip, .Lsheeva_asm_page_mask 308183835Sraj and r2, r0, ip 309183835Sraj rsb r2, r2, #PAGE_SIZE 310183835Sraj cmp r1, r2 311183835Sraj movcc ip, r1 312183835Sraj movcs ip, r2 313183835Sraj1: 314183835Sraj add r3, r0, ip 315183835Sraj sub r2, r3, #1 316183835Sraj /* Disable irqs */ 317271398Sandrew orr r3, lr, #PSR_I | PSR_F 318183835Sraj msr cpsr_c, r3 319183835Sraj mcr p15, 1, r0, c15, c11, 4 /* Inv L2 zone start address */ 320183835Sraj mcr p15, 1, r2, c15, c11, 5 /* Inv L2 zone end address */ 321183835Sraj /* Enable irqs */ 322183835Sraj msr cpsr_c, lr 323183835Sraj 324183835Sraj add r0, r0, ip 325183835Sraj sub r1, r1, ip 326183835Sraj cmp r1, #PAGE_SIZE 327183835Sraj movcc ip, r1 328183835Sraj movcs ip, #PAGE_SIZE 329183835Sraj cmp r1, #0 330183835Sraj bne 1b 331183835Sraj mov r0, #0 332183835Sraj mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */ 333183835Sraj ldr lr, [sp], #4 334183835Sraj RET 335248361SandrewEND(sheeva_l2cache_inv_range) 336183835Sraj 337186933SrajENTRY(sheeva_l2cache_wb_range) 338183835Sraj str lr, [sp, #-4]! 339183835Sraj mrs lr, cpsr 340183835Sraj /* Start with cache line aligned address */ 341186933Sraj ldr ip, .Lsheeva_cache_line_size 342183835Sraj ldr ip, [ip] 343183835Sraj sub ip, ip, #1 344183835Sraj and r2, r0, ip 345183835Sraj add r1, r1, r2 346183835Sraj add r1, r1, ip 347183835Sraj bics r1, r1, ip 348183835Sraj bics r0, r0, ip 349183835Sraj 350186933Sraj ldr ip, .Lsheeva_asm_page_mask 351183835Sraj and r2, r0, ip 352183835Sraj rsb r2, r2, #PAGE_SIZE 353183835Sraj cmp r1, r2 354183835Sraj movcc ip, r1 355183835Sraj movcs ip, r2 356183835Sraj1: 357183835Sraj add r3, r0, ip 358183835Sraj sub r2, r3, #1 359183835Sraj /* Disable irqs */ 360271398Sandrew orr r3, lr, #PSR_I | PSR_F 361183835Sraj msr cpsr_c, r3 362183835Sraj mcr p15, 1, r0, c15, c9, 4 /* Clean L2 zone start address */ 363183835Sraj mcr p15, 1, r2, c15, c9, 5 /* Clean L2 zone end address */ 364183835Sraj /* Enable irqs */ 365183835Sraj msr cpsr_c, lr 366183835Sraj 367183835Sraj add r0, r0, ip 368183835Sraj sub r1, r1, ip 369183835Sraj cmp r1, #PAGE_SIZE 370183835Sraj movcc ip, r1 371183835Sraj movcs ip, #PAGE_SIZE 372183835Sraj cmp r1, #0 373183835Sraj bne 1b 374183835Sraj mov r0, #0 375183835Sraj mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */ 376183835Sraj ldr lr, [sp], #4 377183835Sraj RET 378248361SandrewEND(sheeva_l2cache_wb_range) 379183835Sraj 380186933SrajENTRY(sheeva_l2cache_wbinv_all) 381250695Sgber /* Disable irqs */ 382250695Sgber mrs r1, cpsr 383271398Sandrew orr r2, r1, #PSR_I | PSR_F 384250695Sgber msr cpsr_c, r2 385250695Sgber 386183835Sraj mov r0, #0 387183835Sraj mcr p15, 1, r0, c15, c9, 0 /* Clean L2 */ 388183835Sraj mcr p15, 1, r0, c15, c11, 0 /* Invalidate L2 */ 389250695Sgber 390250695Sgber msr cpsr_c, r1 /* Reenable irqs */ 391250695Sgber 392183835Sraj mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */ 393183835Sraj RET 394248361SandrewEND(sheeva_l2cache_wbinv_all) 395183835Sraj 396191141Sraj/* This function modifies register value as follows: 397191141Sraj * 398191141Sraj * arg1 arg EFFECT (bit value saved into register) 399191141Sraj * 0 0 not changed 400191141Sraj * 0 1 negated 401191141Sraj * 1 0 cleared 402191141Sraj * 1 1 set 403191141Sraj */ 404186933SrajENTRY(sheeva_control_ext) 405183835Sraj mrc p15, 1, r3, c15, c1, 0 /* Read the control register */ 406183835Sraj bic r2, r3, r0 /* Clear bits */ 407183835Sraj eor r2, r2, r1 /* XOR bits */ 408183835Sraj 409183835Sraj teq r2, r3 /* Only write if there is a change */ 410183835Sraj mcrne p15, 1, r2, c15, c1, 0 /* Write new control register */ 411183835Sraj mov r0, r3 /* Return old value */ 412183835Sraj RET 413248361SandrewEND(sheeva_control_ext) 414212825Smav 415212825SmavENTRY(sheeva_cpu_sleep) 416212825Smav mov r0, #0 417212825Smav mcr p15, 0, r0, c7, c10, 4 /* Drain write buffer */ 418212825Smav mcr p15, 0, r0, c7, c0, 4 /* Wait for interrupt */ 419212825Smav mov pc, lr 420248361SandrewEND(sheeva_cpu_sleep) 421212825Smav 422