sys_machdep.c revision 1.11
1/* $NetBSD: sys_machdep.c,v 1.11 2007/03/04 06:00:06 christos 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 <sys/cdefs.h> 35__KERNEL_RCSID(0, "$NetBSD"); 36 37#include "opt_compat_hpux.h" 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#include <m68k/cacheops.h> 49 50/* XXX should be in an include file somewhere */ 51#define CC_PURGE 1 52#define CC_FLUSH 2 53#define CC_IPURGE 4 54#define CC_EXTPURGE 0x80000000 55/* XXX end should be */ 56 57/* 58 * Note that what we do here on 040/060 for BSD is different than for HP-UX. 59 * 60 * In 'pux they either act on a line (len == 16), a page (len == PAGE_SIZE) 61 * or the whole cache (len == anything else). 62 * 63 * In BSD we attempt to be more optimal when acting on "odd" sizes. 64 * For lengths up to 1024 we do all affected lines, up to 2*PAGE_SIZE we 65 * do pages, above that we do the entire cache. 66 */ 67/*ARGSUSED1*/ 68int 69cachectl1(u_long req, vaddr_t addr, size_t len, struct proc *p) 70{ 71 int error = 0; 72 73#if defined(M68040) || defined(M68060) 74 if (mmutype == MMU_68040) { 75 int inc = 0; 76 bool doall = false; 77 paddr_t pa = 0; 78 vaddr_t end = 0; 79#ifdef COMPAT_HPUX 80 extern struct emul emul_hpux; 81 82 if ((p->p_emul == &emul_hpux) && 83 len != 16 && len != PAGE_SIZE) 84 doall = 1; 85#endif 86 87 if (addr == 0 || 88#if defined(M68060) 89 (cputype == CPU_68040 && req & CC_IPURGE) || 90#else 91 (req & CC_IPURGE) || 92#endif 93 ((req & ~CC_EXTPURGE) != CC_PURGE && len > 2 * PAGE_SIZE)) 94 doall = 1; 95 96 if (!doall) { 97 end = addr + len; 98 if (len <= 1024) { 99 addr = addr & ~0xf; 100 inc = 16; 101 } else { 102 addr = addr & ~PGOFSET; 103 inc = PAGE_SIZE; 104 } 105 } 106 do { 107 /* 108 * Convert to physical address if needed. 109 * If translation fails, we perform operation on 110 * entire cache. 111 */ 112 if (!doall && 113 (pa == 0 || m68k_page_offset(addr) == 0)) { 114 if (pmap_extract(p->p_vmspace->vm_map.pmap, 115 addr, &pa) == false) 116 doall = 1; 117 } 118 switch (req) { 119 case CC_EXTPURGE|CC_IPURGE: 120 case CC_IPURGE: 121 if (doall) { 122 DCFA(); 123 ICPA(); 124 } else if (inc == 16) { 125 DCFL(pa); 126 ICPL(pa); 127 } else if (inc == PAGE_SIZE) { 128 DCFP(pa); 129 ICPP(pa); 130 } 131 break; 132 133 case CC_EXTPURGE|CC_PURGE: 134 case CC_PURGE: 135 if (doall) 136 DCFA(); /* note: flush not purge */ 137 else if (inc == 16) 138 DCPL(pa); 139 else if (inc == PAGE_SIZE) 140 DCPP(pa); 141 break; 142 143 case CC_EXTPURGE|CC_FLUSH: 144 case CC_FLUSH: 145 if (doall) 146 DCFA(); 147 else if (inc == 16) 148 DCFL(pa); 149 else if (inc == PAGE_SIZE) 150 DCFP(pa); 151 break; 152 153 default: 154 error = EINVAL; 155 break; 156 } 157 if (doall) 158 break; 159 pa += inc; 160 addr += inc; 161 } while (addr < end); 162 return (error); 163 } 164#endif 165 switch (req) { 166 case CC_EXTPURGE|CC_PURGE: 167 case CC_EXTPURGE|CC_FLUSH: 168#if defined(CACHE_HAVE_PAC) 169 if (ectype == EC_PHYS) 170 PCIA(); 171 /* fall into... */ 172#endif 173 case CC_PURGE: 174 case CC_FLUSH: 175 DCIU(); 176 break; 177 case CC_EXTPURGE|CC_IPURGE: 178#if defined(CACHE_HAVE_PAC) 179 if (ectype == EC_PHYS) 180 PCIA(); 181 else 182#endif 183 DCIU(); 184 /* fall into... */ 185 case CC_IPURGE: 186 ICIA(); 187 break; 188 default: 189 error = EINVAL; 190 break; 191 } 192 return error; 193} 194 195int 196sys_sysarch(struct lwp *l, void *v, register_t *retval) 197{ 198 199 return ENOSYS; 200} 201 202#if defined(amiga) || defined(x68k) 203 204/* 205 * DMA cache control 206 */ 207 208/*ARGSUSED1*/ 209int 210dma_cachectl(void *addr, int len) 211{ 212#if defined(M68040) || defined(M68060) 213 int inc = 0; 214 int pa = 0; 215 void *end; 216 217 if (mmutype != MMU_68040) { 218 return 0; 219 } 220 221 end = addr + len; 222 if (len <= 1024) { 223 addr = (void *)((vaddr_t)addr & ~0xf); 224 inc = 16; 225 } else { 226 addr = (void *)((vaddr_t)addr & ~PGOFSET); 227 inc = PAGE_SIZE; 228 } 229 do { 230 /* 231 * Convert to physical address. 232 */ 233 if (pa == 0 || ((vaddr_t)addr & PGOFSET) == 0) { 234 pa = kvtop(addr); 235 } 236 if (inc == 16) { 237 DCFL(pa); 238 ICPL(pa); 239 } else { 240 DCFP(pa); 241 ICPP(pa); 242 } 243 pa += inc; 244 addr += inc; 245 } while (addr < end); 246#endif /* defined(M68040) || defined(M68060) */ 247 return 0; 248} 249#endif /* defined(amiga) || defined(x68k) */ 250