1 /* $NetBSD: cache.c,v 1.25 2025/12/05 22:48:44 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.25 2025/12/05 22:48:44 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/control.h> 53 #include <sun3/sun3/enable.h> 54 #include <sun3/sun3/machdep.h> 55 56 #define CACHE_LINE 16 /* bytes */ 57 #define VAC_FLUSH_INCR 512 /* bytes */ 58 #define VADDR_MASK 0xfFFffFF /* 28 bits */ 59 60 static void cache_clear_tags(void); 61 62 void 63 cache_flush_page(vaddr_t pgva) 64 { 65 char *va, *endva; 66 int old_dfc, ctl_dfc; 67 int data; 68 69 pgva &= (VADDR_MASK & ~PGOFSET); 70 pgva |= VAC_FLUSH_BASE; 71 72 /* Set up for writes to control space. */ 73 __asm volatile ("movc %%dfc, %0" : "=d" (old_dfc)); 74 ctl_dfc = FC_CONTROL; 75 __asm volatile ("movc %0, %%dfc" : : "d" (ctl_dfc)); 76 77 /* Write to control space for each cache line. */ 78 va = (char *) pgva; 79 endva = (char *) (pgva + PAGE_SIZE); 80 data = VAC_FLUSH_PAGE; 81 82 do { 83 __asm volatile ("movsl %0, %1@" : : "d" (data), "a" (va)); 84 va += VAC_FLUSH_INCR; 85 } while (va < endva); 86 87 /* Restore destination function code. */ 88 __asm volatile ("movc %0, %%dfc" : : "d" (old_dfc)); 89 } 90 91 void 92 cache_flush_segment(vaddr_t sgva) 93 { 94 char *va, *endva; 95 int old_dfc, ctl_dfc; 96 int data; 97 98 sgva &= (VADDR_MASK & ~SEGOFSET); 99 sgva |= VAC_FLUSH_BASE; 100 101 /* Set up for writes to control space. */ 102 __asm volatile ("movc %%dfc, %0" : "=d" (old_dfc)); 103 ctl_dfc = FC_CONTROL; 104 __asm volatile ("movc %0, %%dfc" : : "d" (ctl_dfc)); 105 106 /* Write to control space for each cache line. */ 107 va = (char *) sgva; 108 endva = (char *) (sgva + cache_size); 109 data = VAC_FLUSH_SEGMENT; 110 111 do { 112 __asm volatile ("movsl %0, %1@" : : "d" (data), "a" (va)); 113 va += VAC_FLUSH_INCR; 114 } while (va < endva); 115 116 /* Restore destination function code. */ 117 __asm volatile ("movc %0, %%dfc" : : "d" (old_dfc)); 118 } 119 120 void 121 cache_flush_context(void) 122 { 123 char *va, *endva; 124 int old_dfc, ctl_dfc; 125 int data; 126 127 /* Set up for writes to control space. */ 128 __asm volatile ("movc %%dfc, %0" : "=d" (old_dfc)); 129 ctl_dfc = FC_CONTROL; 130 __asm volatile ("movc %0, %%dfc" : : "d" (ctl_dfc)); 131 132 /* Write to control space for each cache line. */ 133 va = (char *) VAC_FLUSH_BASE; 134 endva = (char *) (VAC_FLUSH_BASE + cache_size); 135 data = VAC_FLUSH_CONTEXT; 136 137 do { 138 __asm volatile ("movsl %0, %1@" : : "d" (data), "a" (va)); 139 va += VAC_FLUSH_INCR; 140 } while (va < endva); 141 142 /* Restore destination function code. */ 143 __asm volatile ("movc %0, %%dfc" : : "d" (old_dfc)); 144 } 145 146 static void 147 cache_clear_tags(void) 148 { 149 char *va, *endva; 150 int old_dfc, ctl_dfc; 151 int data; 152 153 /* Set up for writes to control space. */ 154 __asm volatile ("movc %%dfc, %0" : "=d" (old_dfc)); 155 ctl_dfc = FC_CONTROL; 156 __asm volatile ("movc %0, %%dfc" : : "d" (ctl_dfc)); 157 158 /* Write to control space for each cache line. */ 159 va = (char *) VAC_CACHE_TAGS; 160 endva = (char *) (VAC_CACHE_TAGS + cache_size); 161 data = 0; /* invalid tags */ 162 163 do { 164 __asm volatile ("movsl %0, %1@" : : "d" (data), "a" (va)); 165 va += CACHE_LINE; 166 } while (va < endva); 167 168 /* Restore destination function code. */ 169 __asm volatile ("movc %0, %%dfc" : : "d" (old_dfc)); 170 } 171 172 void 173 cache_enable(void) 174 { 175 int enab_reg; 176 177 if (cache_size == 0) 178 return; 179 180 /* Have to invalidate all tags before enabling the cache. */ 181 cache_clear_tags(); 182 183 /* OK, just set the "enable" bit. */ 184 enab_reg = get_control_byte(SYSTEM_ENAB); 185 enab_reg |= ENA_CACHE; 186 set_control_byte(SYSTEM_ENAB, enab_reg); 187 188 /* Brag... */ 189 printf("cache enabled\n"); 190 } 191