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