1244480Sgonzo/* $NetBSD: cpufunc_asm_arm11x6.S,v 1.1 2012/07/21 12:19:15 skrll Exp $ */ 2244480Sgonzo 3244480Sgonzo/* 4244480Sgonzo * Copyright (c) 2007 Microsoft 5244480Sgonzo * All rights reserved. 6244480Sgonzo * 7244480Sgonzo * Redistribution and use in source and binary forms, with or without 8244480Sgonzo * modification, are permitted provided that the following conditions 9244480Sgonzo * are met: 10244480Sgonzo * 1. Redistributions of source code must retain the above copyright 11244480Sgonzo * notice, this list of conditions and the following disclaimer. 12244480Sgonzo * 2. Redistributions in binary form must reproduce the above copyright 13244480Sgonzo * notice, this list of conditions and the following disclaimer in the 14244480Sgonzo * documentation and/or other materials provided with the distribution. 15244480Sgonzo * 3. All advertising materials mentioning features or use of this software 16244480Sgonzo * must display the following acknowledgement: 17244480Sgonzo * This product includes software developed by Microsoft 18244480Sgonzo * 19244480Sgonzo * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 20244480Sgonzo * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21244480Sgonzo * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22244480Sgonzo * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTERS BE LIABLE FOR ANY DIRECT, 23244480Sgonzo * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24244480Sgonzo * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25244480Sgonzo * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26244480Sgonzo * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27244480Sgonzo * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28244480Sgonzo * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29244480Sgonzo * SUCH DAMAGE. 30244480Sgonzo */ 31244480Sgonzo 32244480Sgonzo/*- 33244480Sgonzo * Copyright (c) 2012 The NetBSD Foundation, Inc. 34244480Sgonzo * All rights reserved. 35244480Sgonzo * 36244480Sgonzo * This code is derived from software contributed to The NetBSD Foundation 37244480Sgonzo * by Eben Upton 38244480Sgonzo * 39244480Sgonzo * Redistribution and use in source and binary forms, with or without 40244480Sgonzo * modification, are permitted provided that the following conditions 41244480Sgonzo * are met: 42244480Sgonzo * 1. Redistributions of source code must retain the above copyright 43244480Sgonzo * notice, this list of conditions and the following disclaimer. 44244480Sgonzo * 2. Redistributions in binary form must reproduce the above copyright 45244480Sgonzo * notice, this list of conditions and the following disclaimer in the 46244480Sgonzo * documentation and/or other materials provided with the distribution. 47244480Sgonzo * 48244480Sgonzo * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 49244480Sgonzo * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 50244480Sgonzo * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 51244480Sgonzo * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 52244480Sgonzo * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 53244480Sgonzo * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 54244480Sgonzo * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 55244480Sgonzo * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 56244480Sgonzo * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 57244480Sgonzo * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 58244480Sgonzo * POSSIBILITY OF SUCH DAMAGE. 59244480Sgonzo */ 60244480Sgonzo 61244480Sgonzo 62244480Sgonzo#include <machine/asm.h> 63244480Sgonzo__FBSDID("$FreeBSD$"); 64244480Sgonzo 65275523Sandrew .cpu arm1176jz-s 66248028Skientzle 67244480Sgonzo#if 0 68244480Sgonzo#define Invalidate_I_cache(Rtmp1, Rtmp2) \ 69244480Sgonzo mcr p15, 0, Rtmp1, c7, c5, 0 /* Invalidate Entire I cache */ 70244480Sgonzo#else 71244480Sgonzo/* 72244480Sgonzo * Workaround for 73244480Sgonzo * 74244480Sgonzo * Erratum 411920 in ARM1136 (fixed in r1p4) 75244480Sgonzo * Erratum 415045 in ARM1176 (fixed in r0p5?) 76283366Sandrew * 77244480Sgonzo * - value of arg 'reg' Should Be Zero 78244480Sgonzo */ 79244480Sgonzo#define Invalidate_I_cache(Rtmp1, Rtmp2) \ 80244480Sgonzo mov Rtmp1, #0; /* SBZ */ \ 81244480Sgonzo mrs Rtmp2, cpsr; \ 82244480Sgonzo cpsid ifa; \ 83244480Sgonzo mcr p15, 0, Rtmp1, c7, c5, 0; /* Nuke Whole Icache */ \ 84244480Sgonzo mcr p15, 0, Rtmp1, c7, c5, 0; /* Nuke Whole Icache */ \ 85244480Sgonzo mcr p15, 0, Rtmp1, c7, c5, 0; /* Nuke Whole Icache */ \ 86244480Sgonzo mcr p15, 0, Rtmp1, c7, c5, 0; /* Nuke Whole Icache */ \ 87244480Sgonzo msr cpsr_cx, Rtmp2; \ 88244480Sgonzo nop; \ 89244480Sgonzo nop; \ 90244480Sgonzo nop; \ 91244480Sgonzo nop; \ 92244480Sgonzo nop; \ 93244480Sgonzo nop; \ 94244480Sgonzo nop; \ 95244480Sgonzo nop; \ 96244480Sgonzo nop; \ 97244480Sgonzo nop; \ 98244480Sgonzo nop; 99244480Sgonzo#endif 100244480Sgonzo 101244480Sgonzo#if 1 102244480Sgonzo#define Flush_D_cache(reg) \ 103244480Sgonzo mov reg, #0; /* SBZ */ \ 104244480Sgonzo mcr p15, 0, reg, c7, c14, 0;/* Clean and Invalidate Entire Data Cache */ \ 105244480Sgonzo mcr p15, 0, reg, c7, c10, 4;/* Data Synchronization Barrier */ 106244480Sgonzo#else 107244480Sgonzo#define Flush_D_cache(reg) \ 108244480Sgonzo1: mov reg, #0; /* SBZ */ \ 109244480Sgonzo mcr p15, 0, reg, c7, c14, 0;/* Clean and Invalidate Entire Data Cache */ \ 110244480Sgonzo mrc p15, 0, reg, C7, C10, 6;/* Read Cache Dirty Status Register */ \ 111244480Sgonzo ands reg, reg, #01; /* Check if it is clean */ \ 112244480Sgonzo bne 1b; /* loop if not */ \ 113244480Sgonzo mcr p15, 0, reg, c7, c10, 4;/* Data Synchronization Barrier */ 114244480Sgonzo#endif 115244480Sgonzo 116244480SgonzoENTRY(arm11x6_setttb) 117244480Sgonzo mov r1, #0 118244480Sgonzo mcr p15, 0, r0, c2, c0, 0 /* load new TTB */ 119244480Sgonzo mcr p15, 0, r1, c8, c7, 0 /* invalidate I+D TLBs */ 120244480Sgonzo mcr p15, 0, r1, c7, c10, 4 /* drain write buffer */ 121244480Sgonzo RET 122248361SandrewEND(arm11x6_setttb) 123244480Sgonzo 124244480SgonzoENTRY_NP(arm11x6_idcache_wbinv_all) 125244480Sgonzo Flush_D_cache(r0) 126244480Sgonzo Invalidate_I_cache(r0, r1) 127244480Sgonzo RET 128248361SandrewEND(arm11x6_idcache_wbinv_all) 129244480Sgonzo 130244480SgonzoENTRY_NP(arm11x6_dcache_wbinv_all) 131244480Sgonzo Flush_D_cache(r0) 132244480Sgonzo RET 133248361SandrewEND(arm11x6_dcache_wbinv_all) 134244480Sgonzo 135244480SgonzoENTRY_NP(arm11x6_icache_sync_range) 136244480Sgonzo add r1, r1, r0 137244480Sgonzo sub r1, r1, #1 138244480Sgonzo /* Erratum ARM1136 371025, workaround #2 */ 139244480Sgonzo /* Erratum ARM1176 371367 */ 140244480Sgonzo mrs r2, cpsr /* save the CPSR */ 141244480Sgonzo cpsid ifa /* disable interrupts (irq,fiq,abort) */ 142283366Sandrew mov r3, #0 143244480Sgonzo mcr p15, 0, r3, c13, c0, 0 /* write FCSE (uTLB invalidate) */ 144244480Sgonzo mcr p15, 0, r3, c7, c5, 4 /* flush prefetch buffer */ 145283366Sandrew add r3, pc, #0x24 146244480Sgonzo mcr p15, 0, r3, c7, c13, 1 /* prefetch I-cache line */ 147244480Sgonzo mcrr p15, 0, r1, r0, c5 /* invalidate I-cache range */ 148244480Sgonzo msr cpsr_cx, r2 /* local_irq_restore */ 149283366Sandrew nop 150283366Sandrew nop 151283366Sandrew nop 152283366Sandrew nop 153283366Sandrew nop 154283366Sandrew nop 155283366Sandrew nop 156244480Sgonzo 157244480Sgonzo mcrr p15, 0, r1, r0, c12 /* clean and invalidate D cache range */ /* XXXNH */ 158244480Sgonzo mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */ 159244480Sgonzo RET 160248361SandrewEND(arm11x6_icache_sync_range) 161244480Sgonzo 162244480SgonzoENTRY_NP(arm11x6_idcache_wbinv_range) 163244480Sgonzo add r1, r1, r0 164244480Sgonzo sub r1, r1, #1 165244480Sgonzo /* Erratum ARM1136 371025, workaround #2 */ 166244480Sgonzo /* Erratum ARM1176 371367 */ 167244480Sgonzo mrs r2, cpsr /* save the CPSR */ 168244480Sgonzo cpsid ifa /* disable interrupts (irq,fiq,abort) */ 169283366Sandrew mov r3, #0 170244480Sgonzo mcr p15, 0, r3, c13, c0, 0 /* write FCSE (uTLB invalidate) */ 171244480Sgonzo mcr p15, 0, r3, c7, c5, 4 /* flush prefetch buffer */ 172283366Sandrew add r3, pc, #0x24 173244480Sgonzo mcr p15, 0, r3, c7, c13, 1 /* prefetch I-cache line */ 174244480Sgonzo mcrr p15, 0, r1, r0, c5 /* invalidate I-cache range */ 175244480Sgonzo msr cpsr_cx, r2 /* local_irq_restore */ 176283366Sandrew nop 177283366Sandrew nop 178283366Sandrew nop 179283366Sandrew nop 180283366Sandrew nop 181283366Sandrew nop 182283366Sandrew nop 183244480Sgonzo 184244480Sgonzo mcrr p15, 0, r1, r0, c14 /* clean and invalidate D cache range */ 185244480Sgonzo mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */ 186244480Sgonzo RET 187248361SandrewEND(arm11x6_idcache_wbinv_range) 188244480Sgonzo 189244480Sgonzo/* 190244480Sgonzo * Preload the cache before issuing the WFI by conditionally disabling the 191283366Sandrew * mcr intstructions the first time around the loop. Ensure the function is 192244480Sgonzo * cacheline aligned. 193244480Sgonzo */ 194244480Sgonzo .arch armv6 195244480Sgonzo .p2align 5 196244480Sgonzo 197244480SgonzoENTRY_NP(arm11x6_sleep) 198244480Sgonzo mov r0, #0 199244480Sgonzo mov r1, #2 200244480Sgonzo1: 201244480Sgonzo subs r1, #1 202244480Sgonzo nop 203244480Sgonzo mcreq p15, 0, r0, c7, c10, 4 /* data sync barrier */ 204244480Sgonzo mcreq p15, 0, r0, c7, c0, 4 /* wait for interrupt */ 205244480Sgonzo nop 206244480Sgonzo nop 207244480Sgonzo nop 208244480Sgonzo bne 1b 209244480Sgonzo RET 210248361SandrewEND(arm11x6_sleep) 211248361Sandrew 212