1 /* $NetBSD: cache.c,v 1.24 2023/12/27 17:35:37 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 1996 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Gordon W. Ross. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * cache flush operations specific to the Sun3 custom MMU 34 * all are done using writes to control space 35 */ 36 37 #include <sys/cdefs.h> 38 __KERNEL_RCSID(0, "$NetBSD: cache.c,v 1.24 2023/12/27 17:35:37 thorpej Exp $"); 39 40 #include <sys/param.h> 41 #include <sys/systm.h> 42 #include <sys/proc.h> 43 #include <sys/queue.h> 44 45 #include <uvm/uvm_extern.h> 46 47 #include <machine/cpu.h> 48 #include <machine/fcode.h> 49 #include <machine/pte.h> 50 #include <machine/vmparam.h> 51 52 #include <sun3/sun3/cache.h> 53 #include <sun3/sun3/control.h> 54 #include <sun3/sun3/enable.h> 55 #include <sun3/sun3/machdep.h> 56 57 #define CACHE_LINE 16 /* bytes */ 58 #define VAC_FLUSH_INCR 512 /* bytes */ 59 #define VADDR_MASK 0xfFFffFF /* 28 bits */ 60 61 static void cache_clear_tags(void); 62 63 void 64 cache_flush_page(vaddr_t pgva) 65 { 66 char *va, *endva; 67 int old_dfc, ctl_dfc; 68 int data; 69 70 pgva &= (VADDR_MASK & ~PGOFSET); 71 pgva |= VAC_FLUSH_BASE; 72 73 /* Set up for writes to control space. */ 74 __asm volatile ("movc %%dfc, %0" : "=d" (old_dfc)); 75 ctl_dfc = FC_CONTROL; 76 __asm volatile ("movc %0, %%dfc" : : "d" (ctl_dfc)); 77 78 /* Write to control space for each cache line. */ 79 va = (char *) pgva; 80 endva = (char *) (pgva + PAGE_SIZE); 81 data = VAC_FLUSH_PAGE; 82 83 do { 84 __asm volatile ("movsl %0, %1@" : : "d" (data), "a" (va)); 85 va += VAC_FLUSH_INCR; 86 } while (va < endva); 87 88 /* Restore destination function code. */ 89 __asm volatile ("movc %0, %%dfc" : : "d" (old_dfc)); 90 } 91 92 void 93 cache_flush_segment(vaddr_t sgva) 94 { 95 char *va, *endva; 96 int old_dfc, ctl_dfc; 97 int data; 98 99 sgva &= (VADDR_MASK & ~SEGOFSET); 100 sgva |= VAC_FLUSH_BASE; 101 102 /* Set up for writes to control space. */ 103 __asm volatile ("movc %%dfc, %0" : "=d" (old_dfc)); 104 ctl_dfc = FC_CONTROL; 105 __asm volatile ("movc %0, %%dfc" : : "d" (ctl_dfc)); 106 107 /* Write to control space for each cache line. */ 108 va = (char *) sgva; 109 endva = (char *) (sgva + cache_size); 110 data = VAC_FLUSH_SEGMENT; 111 112 do { 113 __asm volatile ("movsl %0, %1@" : : "d" (data), "a" (va)); 114 va += VAC_FLUSH_INCR; 115 } while (va < endva); 116 117 /* Restore destination function code. */ 118 __asm volatile ("movc %0, %%dfc" : : "d" (old_dfc)); 119 } 120 121 void 122 cache_flush_context(void) 123 { 124 char *va, *endva; 125 int old_dfc, ctl_dfc; 126 int data; 127 128 /* Set up for writes to control space. */ 129 __asm volatile ("movc %%dfc, %0" : "=d" (old_dfc)); 130 ctl_dfc = FC_CONTROL; 131 __asm volatile ("movc %0, %%dfc" : : "d" (ctl_dfc)); 132 133 /* Write to control space for each cache line. */ 134 va = (char *) VAC_FLUSH_BASE; 135 endva = (char *) (VAC_FLUSH_BASE + cache_size); 136 data = VAC_FLUSH_CONTEXT; 137 138 do { 139 __asm volatile ("movsl %0, %1@" : : "d" (data), "a" (va)); 140 va += VAC_FLUSH_INCR; 141 } while (va < endva); 142 143 /* Restore destination function code. */ 144 __asm volatile ("movc %0, %%dfc" : : "d" (old_dfc)); 145 } 146 147 static void 148 cache_clear_tags(void) 149 { 150 char *va, *endva; 151 int old_dfc, ctl_dfc; 152 int data; 153 154 /* Set up for writes to control space. */ 155 __asm volatile ("movc %%dfc, %0" : "=d" (old_dfc)); 156 ctl_dfc = FC_CONTROL; 157 __asm volatile ("movc %0, %%dfc" : : "d" (ctl_dfc)); 158 159 /* Write to control space for each cache line. */ 160 va = (char *) VAC_CACHE_TAGS; 161 endva = (char *) (VAC_CACHE_TAGS + cache_size); 162 data = 0; /* invalid tags */ 163 164 do { 165 __asm volatile ("movsl %0, %1@" : : "d" (data), "a" (va)); 166 va += CACHE_LINE; 167 } while (va < endva); 168 169 /* Restore destination function code. */ 170 __asm volatile ("movc %0, %%dfc" : : "d" (old_dfc)); 171 } 172 173 void 174 cache_enable(void) 175 { 176 int enab_reg; 177 178 if (cache_size == 0) 179 return; 180 181 /* Have to invalidate all tags before enabling the cache. */ 182 cache_clear_tags(); 183 184 /* OK, just set the "enable" bit. */ 185 enab_reg = get_control_byte(SYSTEM_ENAB); 186 enab_reg |= ENA_CACHE; 187 set_control_byte(SYSTEM_ENAB, enab_reg); 188 189 /* Brag... */ 190 printf("cache enabled\n"); 191 } 192