1 /* $OpenBSD: cache.h,v 1.8 2002/03/15 01:20:04 millert Exp $ */ 2 /* $NetBSD: cache.h,v 1.16 1997/07/06 21:15:14 pk Exp $ */ 3 4 /* 5 * Copyright (c) 1996 6 * The President and Fellows of Harvard College. All rights reserved. 7 * Copyright (c) 1992, 1993 8 * The Regents of the University of California. All rights reserved. 9 * 10 * This software was developed by the Computer Systems Engineering group 11 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 12 * contributed to Berkeley. 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 * 3. All advertising materials mentioning features or use of this software 23 * must display the following acknowledgement: 24 * This product includes software developed by Aaron Brown and 25 * Harvard University. 26 * This product includes software developed by the University of 27 * California, Berkeley and its contributors. 28 * 4. Neither the name of the University nor the names of its contributors 29 * may be used to endorse or promote products derived from this software 30 * without specific prior written permission. 31 * 32 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 33 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 34 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 35 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 36 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 40 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 41 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 42 * SUCH DAMAGE. 43 * 44 * @(#)cache.h 8.1 (Berkeley) 6/11/93 45 */ 46 47 #ifndef SPARC_CACHE_H 48 #define SPARC_CACHE_H 49 50 /* 51 * Sun-4 and Sun-4c virtual address cache. 52 * 53 * Sun-4 virtual caches come in two flavors, write-through (Sun-4c) 54 * and write-back (Sun-4). The write-back caches are much faster 55 * but require a bit more care. 56 * 57 */ 58 enum vactype { VAC_UNKNOWN, VAC_NONE, VAC_WRITETHROUGH, VAC_WRITEBACK }; 59 60 /* 61 * Cache tags can be written in control space, and must be set to 0 62 * (or invalid anyway) before turning on the cache. The tags are 63 * addressed as an array of 32-bit structures of the form: 64 * 65 * struct cache_tag { 66 * u_int :7, (unused; must be zero) 67 * ct_cid:3, (context ID) 68 * ct_w:1, (write flag from PTE) 69 * ct_s:1, (supervisor flag from PTE) 70 * ct_v:1, (set => cache entry is valid) 71 * :3, (unused; must be zero) 72 * ct_tid:14, (cache tag ID) 73 * :2; (unused; must be zero) 74 * }; 75 * 76 * The SPARCstation 1 cache sees virtual addresses as: 77 * 78 * struct cache_va { 79 * u_int :2, (unused; probably copies of va_tid<13>) 80 * cva_tid:14, (tag ID) 81 * cva_line:12, (cache line number) 82 * cva_byte:4; (byte in cache line) 83 * }; 84 * 85 * (The SS2 cache is similar but has half as many lines, each twice as long.) 86 * 87 * Note that, because the 12-bit line ID is `wider' than the page offset, 88 * it is possible to have one page map to two different cache lines. 89 * This can happen whenever two different physical pages have the same bits 90 * in the part of the virtual address that overlaps the cache line ID, i.e., 91 * bits <15:12>. In order to prevent cache duplication, we have to 92 * make sure that no one page has more than one virtual address where 93 * (va1 & 0xf000) != (va2 & 0xf000). (The cache hardware turns off ct_v 94 * when a cache miss occurs on a write, i.e., if va1 is in the cache and 95 * va2 is not, and you write to va2, va1 goes out of the cache. If va1 96 * is in the cache and va2 is not, reading va2 also causes va1 to become 97 * uncached, and the [same] data is then read from main memory into the 98 * cache.) 99 * 100 * The other alternative, of course, is to disable caching of aliased 101 * pages. (In a few cases this might be faster anyway, but we do it 102 * only when forced.) 103 * 104 * The Sun4, since it has an 8K pagesize instead of 4K, needs to check 105 * bits that are one position higher. 106 */ 107 108 /* Some more well-known values: */ 109 110 #define CACHE_ALIAS_DIST_SUN4 0x20000 111 #define CACHE_ALIAS_DIST_SUN4C 0x10000 112 113 #define CACHE_ALIAS_BITS_SUN4 0x1e000 114 #define CACHE_ALIAS_BITS_SUN4C 0xf000 115 116 #define CACHE_ALIAS_DIST_HS128k 0x20000 117 #define CACHE_ALIAS_BITS_HS128k 0x1f000 118 #define CACHE_ALIAS_DIST_HS256k 0x40000 119 #define CACHE_ALIAS_BITS_HS256k 0x3f000 120 121 /* 122 * Assuming a tag format where the least significant bits are the byte offset 123 * into the cache line, and the next-most significant bits are the line id, 124 * we can calculate the appropriate aliasing constants. We also assume that 125 * the linesize and total cache size are powers of 2. 126 */ 127 #define GUESS_CACHE_ALIAS_BITS ((cpuinfo.cacheinfo.c_totalsize - 1) & ~PGOFSET) 128 #define GUESS_CACHE_ALIAS_DIST (cpuinfo.cacheinfo.c_totalsize) 129 130 extern int cache_alias_dist; /* */ 131 extern int cache_alias_bits; 132 133 /* Optimize cache alias macros on single architecture kernels */ 134 #if defined(SUN4) && !defined(SUN4C) && !defined(SUN4M) 135 #define CACHE_ALIAS_DIST CACHE_ALIAS_DIST_SUN4 136 #define CACHE_ALIAS_BITS CACHE_ALIAS_BITS_SUN4 137 #elif !defined(SUN4) && defined(SUN4C) && !defined(SUN4M) 138 #define CACHE_ALIAS_DIST CACHE_ALIAS_DIST_SUN4C 139 #define CACHE_ALIAS_BITS CACHE_ALIAS_BITS_SUN4C 140 #else 141 #define CACHE_ALIAS_DIST cache_alias_dist 142 #define CACHE_ALIAS_BITS cache_alias_bits 143 #endif 144 145 /* 146 * True iff a1 and a2 are `bad' aliases (will cause cache duplication). 147 */ 148 #define BADALIAS(a1, a2) (((int)(a1) ^ (int)(a2)) & CACHE_ALIAS_BITS) 149 150 /* 151 * Routines for dealing with the cache. 152 */ 153 void sun4_cache_enable(void); /* turn it on */ 154 void ms1_cache_enable(void); /* turn it on */ 155 void viking_cache_enable(void); /* turn it on */ 156 void hypersparc_cache_enable(void); /* turn it on */ 157 void swift_cache_enable(void); /* turn it on */ 158 void cypress_cache_enable(void); /* turn it on */ 159 void turbosparc_cache_enable(void); /* turn it on */ 160 161 void sun4_vcache_flush_context(void); /* flush current context */ 162 void sun4_vcache_flush_region(int); /* flush region in cur ctx */ 163 void sun4_vcache_flush_segment(int, int); /* flush seg in cur ctx */ 164 void sun4_vcache_flush_page(int va); /* flush page in cur ctx */ 165 void sun4_cache_flush(caddr_t, u_int); /* flush region */ 166 167 void srmmu_vcache_flush_context(void); /* flush current context */ 168 void srmmu_vcache_flush_region(int); /* flush region in cur ctx */ 169 void srmmu_vcache_flush_segment(int, int); /* flush seg in cur ctx */ 170 void srmmu_vcache_flush_page(int va); /* flush page in cur ctx */ 171 void srmmu_cache_flush(caddr_t, u_int); /* flush region */ 172 void hypersparc_pure_vcache_flush(void); 173 174 void ms1_cache_flush_all(void); 175 void srmmu_cache_flush_all(void); 176 void cypress_cache_flush_all(void); 177 void hypersparc_cache_flush_all(void); 178 179 void ms1_cache_flush(caddr_t, u_int); 180 void viking_cache_flush(caddr_t, u_int); 181 void viking_pcache_flush_line(int, int); 182 void srmmu_pcache_flush_line(int, int); 183 184 extern void sparc_noop(void); 185 186 #define noop_vcache_flush_context \ 187 (void (*)(void)) sparc_noop 188 #define noop_vcache_flush_region \ 189 (void (*)(int)) sparc_noop 190 #define noop_vcache_flush_segment \ 191 (void (*)(int,int)) sparc_noop 192 #define noop_vcache_flush_page \ 193 (void (*)(int)) sparc_noop 194 #define noop_cache_flush \ 195 (void (*)(caddr_t, u_int)) sparc_noop 196 #define noop_pcache_flush_line \ 197 (void (*)(int, int)) sparc_noop 198 #define noop_pure_vcache_flush \ 199 (void (*)(void)) sparc_noop 200 #define noop_cache_flush_all \ 201 (void (*)(void)) sparc_noop 202 203 #define cache_flush_page(va) cpuinfo.vcache_flush_page(va) 204 #define cache_flush_segment(vr,vs) cpuinfo.vcache_flush_segment(vr,vs) 205 #define cache_flush_region(vr) cpuinfo.vcache_flush_region(vr) 206 #define cache_flush_context() cpuinfo.vcache_flush_context() 207 208 /* 209 * Cache control information. 210 */ 211 struct cacheinfo { 212 int c_totalsize; /* total size, in bytes */ 213 /* if split, MAX(icache,dcache) */ 214 int c_enabled; /* true => cache is enabled */ 215 int c_hwflush; /* true => have hardware flush */ 216 int c_linesize; /* line size, in bytes */ 217 int c_l2linesize; /* log2(linesize) */ 218 int c_nlines; /* number of cache lines */ 219 int c_physical; /* true => cache has physical 220 address tags */ 221 int c_associativity; /* # of "buckets" in cache line */ 222 int c_split; /* true => cache is split */ 223 224 int ic_totalsize; /* instruction cache */ 225 int ic_enabled; 226 int ic_linesize; 227 int ic_l2linesize; 228 int ic_nlines; 229 int ic_associativity; 230 231 int dc_totalsize; /* data cache */ 232 int dc_enabled; 233 int dc_linesize; 234 int dc_l2linesize; 235 int dc_nlines; 236 int dc_associativity; 237 238 int ec_totalsize; /* external cache info */ 239 int ec_enabled; 240 int ec_linesize; 241 int ec_l2linesize; 242 int ec_nlines; 243 int ec_associativity; 244 245 enum vactype c_vactype; 246 }; 247 248 #define CACHEINFO cpuinfo.cacheinfo 249 250 /* 251 * Cache control statistics. 252 */ 253 struct cachestats { 254 int cs_npgflush; /* # page flushes */ 255 int cs_nsgflush; /* # seg flushes */ 256 int cs_nrgflush; /* # seg flushes */ 257 int cs_ncxflush; /* # context flushes */ 258 int cs_nraflush; /* # range flushes */ 259 #ifdef notyet 260 int cs_ra[65]; /* pages/range */ 261 #endif 262 }; 263 #endif /* SPARC_CACHE_H */ 264