1201468Srpaulo/* $NetBSD: cpufunc_asm_fa526.S,v 1.3 2008/10/15 16:56:49 matt Exp $*/ 2201468Srpaulo/*- 3201468Srpaulo * Copyright (c) 2008 The NetBSD Foundation, Inc. 4201468Srpaulo * All rights reserved. 5201468Srpaulo * 6201468Srpaulo * This code is derived from software contributed to The NetBSD Foundation 7201468Srpaulo * by Matt Thomas <matt@3am-software.com> 8201468Srpaulo * 9201468Srpaulo * Redistribution and use in source and binary forms, with or without 10201468Srpaulo * modification, are permitted provided that the following conditions 11201468Srpaulo * are met: 12201468Srpaulo * 1. Redistributions of source code must retain the above copyright 13201468Srpaulo * notice, this list of conditions and the following disclaimer. 14201468Srpaulo * 2. Redistributions in binary form must reproduce the above copyright 15201468Srpaulo * notice, this list of conditions and the following disclaimer in the 16201468Srpaulo * documentation and/or other materials provided with the distribution. 17201468Srpaulo * 18201468Srpaulo * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19201468Srpaulo * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20201468Srpaulo * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21201468Srpaulo * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22201468Srpaulo * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23201468Srpaulo * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24201468Srpaulo * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25201468Srpaulo * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26201468Srpaulo * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27201468Srpaulo * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28201468Srpaulo * POSSIBILITY OF SUCH DAMAGE. 29201468Srpaulo */ 30201468Srpaulo 31201468Srpaulo 32201468Srpaulo#include <machine/asm.h> 33201468Srpaulo__FBSDID("$FreeBSD$"); 34201468Srpaulo 35207611Skevlo#ifdef CPU_FA526 36201468Srpaulo#define CACHELINE_SIZE 16 37207611Skevlo#else 38207611Skevlo#define CACHELINE_SIZE 32 39207611Skevlo#endif 40201468Srpaulo 41201468SrpauloENTRY(fa526_setttb) 42201468Srpaulo mov r1, #0 43201468Srpaulo mcr p15, 0, r1, c7, c14, 0 /* clean and invalidate D$ */ 44201468Srpaulo mcr p15, 0, r1, c7, c5, 0 /* invalidate I$ */ 45201468Srpaulo mcr p15, 0, r1, c7, c5, 6 /* invalidate BTB */ 46201468Srpaulo mcr p15, 0, r1, c7, c10, 4 /* drain write and fill buffer */ 47201468Srpaulo 48201468Srpaulo mcr p15, 0, r0, c2, c0, 0 /* Write the TTB */ 49201468Srpaulo 50201468Srpaulo /* If we have updated the TTB we must flush the TLB */ 51201468Srpaulo mcr p15, 0, r1, c8, c7, 0 /* invalidate I+D TLB */ 52201468Srpaulo 53201468Srpaulo /* Make sure that pipeline is emptied */ 54201468Srpaulo mov r0, r0 55201468Srpaulo mov r0, r0 56201468Srpaulo mov pc, lr 57248361SandrewEND(fa526_setttb) 58201468Srpaulo 59201468Srpaulo/* 60201468Srpaulo * TLB functions 61201468Srpaulo */ 62201468SrpauloENTRY(fa526_tlb_flushID_SE) 63201468Srpaulo mcr p15, 0, r0, c8, c7, 1 /* flush Utlb single entry */ 64201468Srpaulo mov pc, lr 65248361SandrewEND(fa526_tlb_flushID_SE) 66201468Srpaulo 67201468SrpauloENTRY(fa526_cpu_sleep) 68201468Srpaulo mov r0, #0 69201468Srpaulo/* nop 70201468Srpaulo nop*/ 71201468Srpaulo mcr p15, 0, r0, c7, c0, 4 /* Wait for interrupt*/ 72201468Srpaulo mov pc, lr 73248361SandrewEND(fa526_cpu_sleep) 74201468Srpaulo 75201468Srpaulo/* 76201468Srpaulo * Cache functions 77201468Srpaulo */ 78201468SrpauloENTRY(fa526_idcache_wbinv_all) 79201468Srpaulo mov r0, #0 80201468Srpaulo mcr p15, 0, r0, c7, c14, 0 /* clean and invalidate D$ */ 81201468Srpaulo mcr p15, 0, r0, c7, c5, 0 /* invalidate I$ */ 82201468Srpaulo mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ 83201468Srpaulo mov pc, lr 84248361SandrewEND(fa526_idcache_wbinv_all) 85201468Srpaulo 86201468SrpauloENTRY(fa526_dcache_wbinv_all) 87201468Srpaulo mov r0, #0 88201468Srpaulo mcr p15, 0, r0, c7, c14, 0 /* clean and invalidate D$ */ 89201468Srpaulo mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ 90201468Srpaulo mov pc, lr 91248361SandrewEND(fa526_dcache_wbinv_all) 92201468Srpaulo 93201468Srpaulo/* 94201468Srpaulo * Soft functions 95201468Srpaulo */ 96201468SrpauloENTRY(fa526_dcache_wbinv_range) 97201468Srpaulo cmp r1, #0x4000 98201468Srpaulo bhs _C_LABEL(fa526_dcache_wbinv_all) 99201468Srpaulo 100201468Srpaulo and r2, r0, #(CACHELINE_SIZE - 1) 101201468Srpaulo add r1, r1, r2 102201468Srpaulo bic r0, r0, #(CACHELINE_SIZE - 1) 103201468Srpaulo 104201468Srpaulo1: mcr p15, 0, r0, c7, c14, 1 /* clean and invalidate D$ entry */ 105201468Srpaulo add r0, r0, #CACHELINE_SIZE 106201468Srpaulo subs r1, r1, #CACHELINE_SIZE 107201468Srpaulo bhi 1b 108201468Srpaulo 109201468Srpaulo mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ 110201468Srpaulo mov pc, lr 111248361SandrewEND(fa526_dcache_wbinv_range) 112201468Srpaulo 113201468SrpauloENTRY(fa526_dcache_wb_range) 114201468Srpaulo cmp r1, #0x4000 115201468Srpaulo bls 1f 116201468Srpaulo 117201468Srpaulo mov r0, #0 118201468Srpaulo mcr p15, 0, r0, c7, c10, 0 /* clean entire D$ */ 119201468Srpaulo b 3f 120201468Srpaulo 121201468Srpaulo1: and r2, r0, #(CACHELINE_SIZE - 1) 122201468Srpaulo add r1, r1, r2 123201468Srpaulo bic r0, r0, #(CACHELINE_SIZE - 1) 124201468Srpaulo 125201468Srpaulo2: mcr p15, 0, r0, c7, c10, 1 /* clean D$ entry */ 126201468Srpaulo add r0, r0, #CACHELINE_SIZE 127201468Srpaulo subs r1, r1, #CACHELINE_SIZE 128201468Srpaulo bhi 2b 129201468Srpaulo 130201468Srpaulo3: mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ 131201468Srpaulo mov pc, lr 132248361SandrewEND(fa526_dcache_wb_range) 133201468Srpaulo 134201468SrpauloENTRY(fa526_dcache_inv_range) 135201468Srpaulo and r2, r0, #(CACHELINE_SIZE - 1) 136201468Srpaulo add r1, r1, r2 137201468Srpaulo bic r0, r0, #(CACHELINE_SIZE - 1) 138201468Srpaulo 139201468Srpaulo1: mcr p15, 0, r0, c7, c6, 1 /* invalidate D$ single entry */ 140201468Srpaulo add r0, r0, #CACHELINE_SIZE 141201468Srpaulo subs r1, r1, #CACHELINE_SIZE 142201468Srpaulo bhi 1b 143201468Srpaulo 144201468Srpaulo mov pc, lr 145248361SandrewEND(fa526_dcache_inv_range) 146201468Srpaulo 147201468SrpauloENTRY(fa526_idcache_wbinv_range) 148201468Srpaulo cmp r1, #0x4000 149201468Srpaulo bhs _C_LABEL(fa526_idcache_wbinv_all) 150201468Srpaulo 151201468Srpaulo and r2, r0, #(CACHELINE_SIZE - 1) 152201468Srpaulo add r1, r1, r2 153201468Srpaulo bic r0, r0, #(CACHELINE_SIZE - 1) 154201468Srpaulo 155201468Srpaulo1: mcr p15, 0, r0, c7, c14, 1 /* clean and invalidate D$ entry */ 156201468Srpaulo mcr p15, 0, r0, c7, c5, 1 /* invalidate I$ entry */ 157201468Srpaulo add r0, r0, #CACHELINE_SIZE 158201468Srpaulo subs r1, r1, #CACHELINE_SIZE 159201468Srpaulo bhi 1b 160201468Srpaulo 161201468Srpaulo2: mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ 162201468Srpaulo mov pc, lr 163248361SandrewEND(fa526_idcache_wbinv_range) 164201468Srpaulo 165201468SrpauloENTRY(fa526_icache_sync_range) 166201468Srpaulo cmp r1, #0x4000 167295207Smmel bhs .Lfa526_icache_sync_all 168201468Srpaulo 169201468Srpaulo and r2, r0, #(CACHELINE_SIZE - 1) 170201468Srpaulo add r1, r1, r2 171201468Srpaulo bic r0, r0, #(CACHELINE_SIZE - 1) 172201468Srpaulo 173201468Srpaulo1: mcr p15, 0, r0, c7, c10, 1 /* clean D$ entry */ 174201468Srpaulo mcr p15, 0, r0, c7, c5, 1 /* invalidate I$ entry */ 175201468Srpaulo add r0, r0, #CACHELINE_SIZE 176201468Srpaulo subs r1, r1, #CACHELINE_SIZE 177201468Srpaulo bhi 1b 178201468Srpaulo 179201468Srpaulo2: mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ 180201468Srpaulo mov pc, lr 181295207Smmel 182295207Smmel.Lfa526_icache_sync_all: 183295207Smmel mov r0, #0 184295207Smmel mcr p15, 0, r0, c7, c5, 0 /* invalidate I$ */ 185295207Smmel mov pc, lr 186248361SandrewEND(fa526_icache_sync_range) 187201468Srpaulo 188201468SrpauloENTRY(fa526_context_switch) 189201468Srpaulo /* 190201468Srpaulo * CF_CACHE_PURGE_ID will *ALWAYS* be called prior to this. 191201468Srpaulo * Thus the data cache will contain only kernel data and the 192201468Srpaulo * instruction cache will contain only kernel code, and all 193201468Srpaulo * kernel mappings are shared by all processes. 194201468Srpaulo */ 195201468Srpaulo 196201468Srpaulo mcr p15, 0, r0, c2, c0, 0 /* Write the TTB */ 197201468Srpaulo 198201468Srpaulo /* If we have updated the TTB we must flush the TLB */ 199201468Srpaulo mov r0, #0 200201468Srpaulo mcr p15, 0, r0, c8, c7, 0 /* flush the I+D tlb */ 201201468Srpaulo 202201468Srpaulo /* Make sure that pipeline is emptied */ 203201468Srpaulo mov r0, r0 204201468Srpaulo mov r0, r0 205201468Srpaulo mov pc, lr 206248361SandrewEND(fa526_context_switch) 207201468Srpaulo 208