1 /* $NetBSD: sys_machdep.c,v 1.19 2026/05/06 04:45:04 thorpej Exp $ */ 2 3 /* 4 * Copyright (c) 1982, 1986, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * 31 * @(#)sys_machdep.c 8.2 (Berkeley) 1/13/94 32 */ 33 34 #include "opt_m68k_arch.h" 35 36 #include <sys/cdefs.h> 37 __KERNEL_RCSID(0, "$NetBSD: sys_machdep.c,v 1.19 2026/05/06 04:45:04 thorpej Exp $"); 38 39 #include <sys/param.h> 40 #include <sys/proc.h> 41 #include <sys/mount.h> 42 43 #include <uvm/uvm_extern.h> 44 45 #include <sys/syscallargs.h> 46 47 #include <machine/cpu.h> 48 49 #ifndef __mc68010__ 50 #include <m68k/cacheops.h> 51 52 /* XXX should be in an include file somewhere */ 53 #define CC_PURGE 1 54 #define CC_FLUSH 2 55 #define CC_IPURGE 4 56 #define CC_EXTPURGE 0x80000000 57 /* XXX end should be */ 58 59 /* 60 * Note that what we do here on 040/060 for BSD is different than for HP-UX. 61 * 62 * In 'pux they either act on a line (len == 16), a page (len == PAGE_SIZE) 63 * or the whole cache (len == anything else). 64 * 65 * In BSD we attempt to be more optimal when acting on "odd" sizes. 66 * For lengths up to 1024 we do all affected lines, up to 2*PAGE_SIZE we 67 * do pages, above that we do the entire cache. 68 */ 69 /*ARGSUSED1*/ 70 int 71 cachectl1(u_long req, vaddr_t addr, size_t len, struct proc *p) 72 { 73 int error = 0; 74 75 #if defined(M68040) || defined(M68060) 76 if (cputype >= CPU_68040) { 77 int inc = 0; 78 bool doall = false; 79 paddr_t pa = 0; 80 vaddr_t end = 0; 81 82 if (addr == 0 || 83 #if defined(M68060) 84 (cputype == CPU_68040 && req & CC_IPURGE) || 85 #else 86 (req & CC_IPURGE) || 87 #endif 88 ((req & ~CC_EXTPURGE) != CC_PURGE && len > 2 * PAGE_SIZE)) 89 doall = 1; 90 91 if (!doall) { 92 end = addr + len; 93 if (len <= 1024) { 94 addr = addr & ~0xf; 95 inc = 16; 96 } else { 97 addr = m68k_trunc_page(addr); 98 inc = PAGE_SIZE; 99 } 100 } 101 do { 102 /* 103 * Convert to physical address if needed. 104 * If translation fails, we perform operation on 105 * entire cache. 106 */ 107 if (!doall && 108 (pa == 0 || m68k_page_offset(addr) == 0)) { 109 if (pmap_extract(p->p_vmspace->vm_map.pmap, 110 addr, &pa) == false) 111 doall = 1; 112 } 113 switch (req) { 114 case CC_EXTPURGE|CC_IPURGE: 115 case CC_IPURGE: 116 if (doall) { 117 DCFA(); 118 ICPA(); 119 } else if (inc == 16) { 120 DCFL(pa); 121 ICPL(pa); 122 } else if (inc == PAGE_SIZE) { 123 DCFP(pa); 124 ICPP(pa); 125 } 126 break; 127 128 case CC_EXTPURGE|CC_PURGE: 129 case CC_PURGE: 130 if (doall) 131 DCFA(); /* note: flush not purge */ 132 else if (inc == 16) 133 DCPL(pa); 134 else if (inc == PAGE_SIZE) 135 DCPP(pa); 136 break; 137 138 case CC_EXTPURGE|CC_FLUSH: 139 case CC_FLUSH: 140 if (doall) 141 DCFA(); 142 else if (inc == 16) 143 DCFL(pa); 144 else if (inc == PAGE_SIZE) 145 DCFP(pa); 146 break; 147 148 default: 149 error = EINVAL; 150 break; 151 } 152 if (doall) 153 break; 154 pa += inc; 155 addr += inc; 156 } while (addr < end); 157 return (error); 158 } 159 #endif /* M68040 || M68060 */ 160 161 /* XXX What about EC_VIRT machines? */ 162 switch (req) { 163 case CC_EXTPURGE|CC_PURGE: 164 case CC_EXTPURGE|CC_FLUSH: 165 #if defined(M68K_EC_PAC) 166 if (ectype == EC_PHYS) 167 PCIA(); 168 /* fall into... */ 169 #endif 170 case CC_PURGE: 171 case CC_FLUSH: 172 DCIU(); 173 break; 174 case CC_EXTPURGE|CC_IPURGE: 175 #if defined(M68K_EC_PAC) 176 if (ectype == EC_PHYS) 177 PCIA(); 178 else 179 #endif 180 DCIU(); 181 /* fall into... */ 182 case CC_IPURGE: 183 ICIA(); 184 break; 185 default: 186 error = EINVAL; 187 break; 188 } 189 return error; 190 } 191 192 #if defined(amiga) || defined(x68k) /* XXX XXX XXX */ 193 /* 194 * DMA cache control 195 */ 196 197 /*ARGSUSED1*/ 198 int 199 dma_cachectl(void *addr, int len) 200 { 201 #if defined(M68040) || defined(M68060) 202 int inc = 0; 203 int pa = 0; 204 void *end; 205 206 if (mmutype != MMU_68040) { 207 return 0; 208 } 209 210 end = (char*)addr + len; 211 if (len <= 1024) { 212 addr = (void *)((vaddr_t)addr & ~0xf); 213 inc = 16; 214 } else { 215 addr = (void *)m68k_trunc_page(addr); 216 inc = PAGE_SIZE; 217 } 218 do { 219 /* 220 * Convert to physical address. 221 */ 222 if (pa == 0 || ((vaddr_t)addr & PAGE_MASK) == 0) { 223 pa = kvtop(addr); 224 } 225 if (inc == 16) { 226 DCFL(pa); 227 ICPL(pa); 228 } else { 229 DCFP(pa); 230 ICPP(pa); 231 } 232 pa += inc; 233 addr = (char*)addr + inc; 234 } while (addr < end); 235 #endif /* defined(M68040) || defined(M68060) */ 236 return 0; 237 } 238 #endif /* defined(amiga) || defined(x68k) */ 239 240 #endif /* ! __mc68010__ */ 241 242 int 243 sys_sysarch(struct lwp *l, const struct sys_sysarch_args *uap, 244 register_t *retval) 245 { 246 247 return ENOSYS; 248 } 249