Home | History | Annotate | Line # | Download | only in booke
booke_cache.c revision 1.1.2.2
      1 /*	$NetBSD: booke_cache.c,v 1.1.2.2 2011/10/14 17:21:25 matt 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.1.2.2 2011/10/14 17:21:25 matt Exp $");
     42 
     43 #include <sys/param.h>
     44 #include <sys/cpu.h>
     45 #include <sys/atomic.h>
     46 
     47 #include <machine/vmparam.h>
     48 
     49 enum cache_op { OP_DCBF, OP_DCBST, OP_DCBI, OP_DCBZ, OP_DCBA, OP_ICBI };
     50 
     51 static void inline
     52 dcbf(vaddr_t va, vsize_t off)
     53 {
     54 	__asm volatile("dcbf\t%0,%1" : : "b" (va), "r" (off));
     55 }
     56 
     57 static void inline
     58 dcbst(vaddr_t va, vsize_t off)
     59 {
     60 	__asm volatile("dcbst\t%0,%1" : : "b" (va), "r" (off));
     61 }
     62 
     63 static void inline
     64 dcbi(vaddr_t va, vsize_t off)
     65 {
     66 	__asm volatile("dcbi\t%0,%1" : : "b" (va), "r" (off));
     67 }
     68 
     69 static void inline
     70 dcbz(vaddr_t va, vsize_t off)
     71 {
     72 	__asm volatile("dcbz\t%0,%1" : : "b" (va), "r" (off));
     73 }
     74 
     75 static void inline
     76 dcba(vaddr_t va, vsize_t off)
     77 {
     78 	__asm volatile("dcba\t%0,%1" : : "b" (va), "r" (off));
     79 }
     80 
     81 static void inline
     82 icbi(vaddr_t va, vsize_t off)
     83 {
     84 	__asm volatile("icbi\t%0,%1" : : "b" (va), "r" (off));
     85 }
     86 
     87 static inline void
     88 cache_op(vaddr_t va, vsize_t len, vsize_t line_size, enum cache_op op)
     89 {
     90 	KASSERT(line_size > 0);
     91 
     92 	if (len == 0)
     93 		return;
     94 
     95 	/* Make sure we flush all cache lines */
     96 	len += va & (line_size - 1);
     97 	va &= -line_size;
     98 
     99 	for (vsize_t i = 0; i < len; i += line_size) {
    100 		switch (op) {
    101 		case OP_DCBF: dcbf(va, i); break;
    102 		case OP_DCBST: dcbst(va, i); break;
    103 		case OP_DCBI: dcbi(va, i); break;
    104 		case OP_DCBZ: dcbz(va, i); break;
    105 		case OP_DCBA: dcba(va, i); break;
    106 		case OP_ICBI: icbi(va, i); break;
    107 		}
    108 	}
    109 	if (op != OP_ICBI)
    110 		membar_producer();
    111 }
    112 
    113 void
    114 dcache_wb_page(vaddr_t va)
    115 {
    116 	cache_op(va, PAGE_SIZE, curcpu()->ci_ci.dcache_line_size, OP_DCBST);
    117 }
    118 
    119 void
    120 dcache_wbinv_page(vaddr_t va)
    121 {
    122 	cache_op(va, PAGE_SIZE, curcpu()->ci_ci.dcache_line_size, OP_DCBF);
    123 }
    124 
    125 void
    126 dcache_inv_page(vaddr_t va)
    127 {
    128 	cache_op(va, PAGE_SIZE, curcpu()->ci_ci.dcache_line_size, OP_DCBI);
    129 }
    130 
    131 void
    132 dcache_zero_page(vaddr_t va)
    133 {
    134 	cache_op(va, PAGE_SIZE, curcpu()->ci_ci.dcache_line_size, OP_DCBZ);
    135 }
    136 
    137 void
    138 icache_inv_page(vaddr_t va)
    139 {
    140 	membar_sync();
    141 	cache_op(va, PAGE_SIZE, curcpu()->ci_ci.icache_line_size, OP_ICBI);
    142 	membar_sync();
    143 	/* synchronizing instruction will be the rfi to user mode */
    144 }
    145 
    146 void
    147 dcache_wb(vaddr_t va, vsize_t len)
    148 {
    149 	cache_op(va, len, curcpu()->ci_ci.dcache_line_size, OP_DCBST);
    150 }
    151 
    152 void
    153 dcache_wbinv(vaddr_t va, vsize_t len)
    154 {
    155 	cache_op(va, len, curcpu()->ci_ci.dcache_line_size, OP_DCBF);
    156 }
    157 
    158 void
    159 dcache_inv(vaddr_t va, vsize_t len)
    160 {
    161 	cache_op(va, len, curcpu()->ci_ci.dcache_line_size, OP_DCBI);
    162 }
    163 
    164 void
    165 icache_inv(vaddr_t va, vsize_t len)
    166 {
    167 	membar_sync();
    168 	cache_op(va, len, curcpu()->ci_ci.icache_line_size, OP_ICBI);
    169 	membar_sync();
    170 }
    171