booke_cache.c revision 1.4
1/* $NetBSD: booke_cache.c,v 1.4 2011/06/29 21:53:10 dholland Exp $ */ 2/*- 3 * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to The NetBSD Foundation 7 * by Raytheon BBN Technologies Corp and Defense Advanced Research Projects 8 * Agency and which was developed by Matt Thomas of 3am Software Foundry. 9 * 10 * This material is based upon work supported by the Defense Advanced Research 11 * Projects Agency and Space and Naval Warfare Systems Center, Pacific, under 12 * Contract No. N66001-09-C-2073. 13 * Approved for Public Release, Distribution Unlimited 14 * 15 * Redistribution and use in source and binary forms, with or without 16 * modification, are permitted provided that the following conditions 17 * are met: 18 * 1. Redistributions of source code must retain the above copyright 19 * notice, this list of conditions and the following disclaimer. 20 * 2. Redistributions in binary form must reproduce the above copyright 21 * notice, this list of conditions and the following disclaimer in the 22 * documentation and/or other materials provided with the distribution. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 25 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 26 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 27 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 28 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 * POSSIBILITY OF SUCH DAMAGE. 35 */ 36/* 37 * 38 */ 39#include <sys/cdefs.h> 40 41__KERNEL_RCSID(0, "$NetBSD: booke_cache.c,v 1.4 2011/06/29 21:53:10 dholland Exp $"); 42 43#include <sys/param.h> 44#include <sys/cpu.h> 45#include <sys/atomic.h> 46 47enum cache_op { OP_DCBF, OP_DCBST, OP_DCBI, OP_DCBZ, OP_DCBA, OP_ICBI }; 48 49static void inline 50dcbf(vaddr_t va, vsize_t off) 51{ 52 __asm volatile("dcbf\t%0,%1" : : "b" (va), "r" (off)); 53} 54 55static void inline 56dcbst(vaddr_t va, vsize_t off) 57{ 58 __asm volatile("dcbst\t%0,%1" : : "b" (va), "r" (off)); 59} 60 61static void inline 62dcbi(vaddr_t va, vsize_t off) 63{ 64 __asm volatile("dcbi\t%0,%1" : : "b" (va), "r" (off)); 65} 66 67static void inline 68dcbz(vaddr_t va, vsize_t off) 69{ 70 __asm volatile("dcbz\t%0,%1" : : "b" (va), "r" (off)); 71} 72 73static void inline 74dcba(vaddr_t va, vsize_t off) 75{ 76 __asm volatile("dcba\t%0,%1" : : "b" (va), "r" (off)); 77} 78 79static void inline 80icbi(vaddr_t va, vsize_t off) 81{ 82 __asm volatile("icbi\t%0,%1" : : "b" (va), "r" (off)); 83} 84 85static inline void 86cache_op(vaddr_t va, vsize_t len, vsize_t line_size, enum cache_op op) 87{ 88 KASSERT(line_size > 0); 89 90 if (len == 0) 91 return; 92 93 /* Make sure we flush all cache lines */ 94 len += va & (line_size - 1); 95 va &= -line_size; 96 97 for (vsize_t i = 0; i < len; i += line_size) { 98 switch (op) { 99 case OP_DCBF: dcbf(va, i); break; 100 case OP_DCBST: dcbst(va, i); break; 101 case OP_DCBI: dcbi(va, i); break; 102 case OP_DCBZ: dcbz(va, i); break; 103 case OP_DCBA: dcba(va, i); break; 104 case OP_ICBI: icbi(va, i); break; 105 } 106 } 107 if (op != OP_ICBI) 108 membar_producer(); 109} 110 111void 112dcache_wb_page(vaddr_t va) 113{ 114 cache_op(va, PAGE_SIZE, curcpu()->ci_ci.dcache_line_size, OP_DCBST); 115} 116 117void 118dcache_wbinv_page(vaddr_t va) 119{ 120 cache_op(va, PAGE_SIZE, curcpu()->ci_ci.dcache_line_size, OP_DCBF); 121} 122 123void 124dcache_inv_page(vaddr_t va) 125{ 126 cache_op(va, PAGE_SIZE, curcpu()->ci_ci.dcache_line_size, OP_DCBI); 127} 128 129void 130dcache_zero_page(vaddr_t va) 131{ 132 cache_op(va, PAGE_SIZE, curcpu()->ci_ci.dcache_line_size, OP_DCBZ); 133} 134 135void 136icache_inv_page(vaddr_t va) 137{ 138 membar_sync(); 139 cache_op(va, PAGE_SIZE, curcpu()->ci_ci.icache_line_size, OP_ICBI); 140 membar_sync(); 141 /* synchronizing instruction will be the rfi to user mode */ 142} 143 144void 145dcache_wb(vaddr_t va, vsize_t len) 146{ 147 cache_op(va, len, curcpu()->ci_ci.dcache_line_size, OP_DCBST); 148} 149 150void 151dcache_wbinv(vaddr_t va, vsize_t len) 152{ 153 cache_op(va, len, curcpu()->ci_ci.dcache_line_size, OP_DCBF); 154} 155 156void 157dcache_inv(vaddr_t va, vsize_t len) 158{ 159 cache_op(va, len, curcpu()->ci_ci.dcache_line_size, OP_DCBI); 160} 161 162void 163icache_inv(vaddr_t va, vsize_t len) 164{ 165 membar_sync(); 166 cache_op(va, len, curcpu()->ci_ci.icache_line_size, OP_ICBI); 167 membar_sync(); 168} 169