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