1/* $NetBSD: cpufunc_asm_fa526.S,v 1.3 2008/10/15 16:56:49 matt Exp $*/ 2/*- 3 * Copyright (c) 2008 The NetBSD Foundation, Inc. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to The NetBSD Foundation 7 * by Matt Thomas <matt@3am-software.com> 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 32#include <machine/asm.h> 33__FBSDID("$FreeBSD$"); 34 35#ifdef CPU_FA526 36#define CACHELINE_SIZE 16 37#else 38#define CACHELINE_SIZE 32 39#endif 40 41ENTRY(fa526_setttb) 42 mov r1, #0 43 mcr p15, 0, r1, c7, c14, 0 /* clean and invalidate D$ */ 44 mcr p15, 0, r1, c7, c5, 0 /* invalidate I$ */ 45 mcr p15, 0, r1, c7, c5, 6 /* invalidate BTB */ 46 mcr p15, 0, r1, c7, c10, 4 /* drain write and fill buffer */ 47 48 mcr p15, 0, r0, c2, c0, 0 /* Write the TTB */ 49 50 /* If we have updated the TTB we must flush the TLB */ 51 mcr p15, 0, r1, c8, c7, 0 /* invalidate I+D TLB */ 52 53 /* Make sure that pipeline is emptied */ 54 mov r0, r0 55 mov r0, r0 56 mov pc, lr 57 58/* 59 * TLB functions 60 */ 61ENTRY(fa526_tlb_flushID_SE) 62 mcr p15, 0, r0, c8, c7, 1 /* flush Utlb single entry */ 63 mov pc, lr 64 65/* 66 * TLB functions 67 */ 68ENTRY(fa526_tlb_flushI_SE) 69 mcr p15, 0, r0, c8, c5, 1 /* flush Itlb single entry */ 70 mov pc, lr 71 72ENTRY(fa526_cpu_sleep) 73 mov r0, #0 74/* nop 75 nop*/ 76 mcr p15, 0, r0, c7, c0, 4 /* Wait for interrupt*/ 77 mov pc, lr 78 79ENTRY(fa526_flush_prefetchbuf) 80 mov r0, #0 81 mcr p15, 0, r0, c7, c5, 4 /* Pre-fetch flush */ 82 mov pc, lr 83 84/* 85 * Cache functions 86 */ 87ENTRY(fa526_idcache_wbinv_all) 88 mov r0, #0 89 mcr p15, 0, r0, c7, c14, 0 /* clean and invalidate D$ */ 90 mcr p15, 0, r0, c7, c5, 0 /* invalidate I$ */ 91 mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ 92 mov pc, lr 93 94ENTRY(fa526_icache_sync_all) 95 mov r0, #0 96 mcr p15, 0, r0, c7, c5, 0 /* invalidate I$ */ 97 mov pc, lr 98 99ENTRY(fa526_dcache_wbinv_all) 100 mov r0, #0 101 mcr p15, 0, r0, c7, c14, 0 /* clean and invalidate D$ */ 102 mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ 103 mov pc, lr 104 105/* 106 * Soft functions 107 */ 108ENTRY(fa526_dcache_wbinv_range) 109 cmp r1, #0x4000 110 bhs _C_LABEL(fa526_dcache_wbinv_all) 111 112 and r2, r0, #(CACHELINE_SIZE - 1) 113 add r1, r1, r2 114 bic r0, r0, #(CACHELINE_SIZE - 1) 115 1161: mcr p15, 0, r0, c7, c14, 1 /* clean and invalidate D$ entry */ 117 add r0, r0, #CACHELINE_SIZE 118 subs r1, r1, #CACHELINE_SIZE 119 bhi 1b 120 121 mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ 122 mov pc, lr 123 124ENTRY(fa526_dcache_wb_range) 125 cmp r1, #0x4000 126 bls 1f 127 128 mov r0, #0 129 mcr p15, 0, r0, c7, c10, 0 /* clean entire D$ */ 130 b 3f 131 1321: and r2, r0, #(CACHELINE_SIZE - 1) 133 add r1, r1, r2 134 bic r0, r0, #(CACHELINE_SIZE - 1) 135 1362: mcr p15, 0, r0, c7, c10, 1 /* clean D$ entry */ 137 add r0, r0, #CACHELINE_SIZE 138 subs r1, r1, #CACHELINE_SIZE 139 bhi 2b 140 1413: mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ 142 mov pc, lr 143 144ENTRY(fa526_dcache_inv_range) 145 and r2, r0, #(CACHELINE_SIZE - 1) 146 add r1, r1, r2 147 bic r0, r0, #(CACHELINE_SIZE - 1) 148 1491: mcr p15, 0, r0, c7, c6, 1 /* invalidate D$ single entry */ 150 add r0, r0, #CACHELINE_SIZE 151 subs r1, r1, #CACHELINE_SIZE 152 bhi 1b 153 154 mov pc, lr 155 156ENTRY(fa526_idcache_wbinv_range) 157 cmp r1, #0x4000 158 bhs _C_LABEL(fa526_idcache_wbinv_all) 159 160 and r2, r0, #(CACHELINE_SIZE - 1) 161 add r1, r1, r2 162 bic r0, r0, #(CACHELINE_SIZE - 1) 163 1641: mcr p15, 0, r0, c7, c14, 1 /* clean and invalidate D$ entry */ 165 mcr p15, 0, r0, c7, c5, 1 /* invalidate I$ entry */ 166 add r0, r0, #CACHELINE_SIZE 167 subs r1, r1, #CACHELINE_SIZE 168 bhi 1b 169 1702: mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ 171 mov pc, lr 172 173ENTRY(fa526_icache_sync_range) 174 cmp r1, #0x4000 175 bhs _C_LABEL(fa526_icache_sync_all) 176 177 and r2, r0, #(CACHELINE_SIZE - 1) 178 add r1, r1, r2 179 bic r0, r0, #(CACHELINE_SIZE - 1) 180 1811: mcr p15, 0, r0, c7, c10, 1 /* clean D$ entry */ 182 mcr p15, 0, r0, c7, c5, 1 /* invalidate I$ entry */ 183 add r0, r0, #CACHELINE_SIZE 184 subs r1, r1, #CACHELINE_SIZE 185 bhi 1b 186 1872: mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ 188 mov pc, lr 189 190ENTRY(fa526_flush_brnchtgt_E) 191 mov r0, #0 192 mcr p15, 0, r0, c7, c5, 6 /* invalidate BTB cache */ 193 mov pc, lr 194 195ENTRY(fa526_context_switch) 196 /* 197 * CF_CACHE_PURGE_ID will *ALWAYS* be called prior to this. 198 * Thus the data cache will contain only kernel data and the 199 * instruction cache will contain only kernel code, and all 200 * kernel mappings are shared by all processes. 201 */ 202 203 mcr p15, 0, r0, c2, c0, 0 /* Write the TTB */ 204 205 /* If we have updated the TTB we must flush the TLB */ 206 mov r0, #0 207 mcr p15, 0, r0, c8, c7, 0 /* flush the I+D tlb */ 208 209 /* Make sure that pipeline is emptied */ 210 mov r0, r0 211 mov r0, r0 212 mov pc, lr 213 214