1 /* 2 * Copyright (c) 1982, 1986, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)sys_machdep.c 8.2 (Berkeley) 01/13/94 8 */ 9 10 #include <sys/param.h> 11 #include <sys/systm.h> 12 #include <sys/ioctl.h> 13 #include <sys/file.h> 14 #include <sys/time.h> 15 #include <sys/proc.h> 16 #include <sys/uio.h> 17 #include <sys/kernel.h> 18 #include <sys/mtio.h> 19 #include <sys/buf.h> 20 #include <sys/trace.h> 21 22 #include <vm/vm.h> 23 24 #ifdef TRACE 25 int nvualarm; 26 27 struct vtrace_args { 28 int request; 29 int value; 30 }; 31 vtrace(p, uap, retval) 32 struct proc *p; 33 register struct vtrace_args *uap; 34 int *retval; 35 { 36 int vdoualarm(); 37 38 switch (uap->request) { 39 40 case VTR_DISABLE: /* disable a trace point */ 41 case VTR_ENABLE: /* enable a trace point */ 42 if (uap->value < 0 || uap->value >= TR_NFLAGS) 43 return (EINVAL); 44 *retval = traceflags[uap->value]; 45 traceflags[uap->value] = uap->request; 46 break; 47 48 case VTR_VALUE: /* return a trace point setting */ 49 if (uap->value < 0 || uap->value >= TR_NFLAGS) 50 return (EINVAL); 51 *retval = traceflags[uap->value]; 52 break; 53 54 case VTR_UALARM: /* set a real-time ualarm, less than 1 min */ 55 if (uap->value <= 0 || uap->value > 60 * hz || nvualarm > 5) 56 return (EINVAL); 57 nvualarm++; 58 timeout(vdoualarm, (caddr_t)p->p_pid, uap->value); 59 break; 60 61 case VTR_STAMP: 62 trace(TR_STAMP, uap->value, p->p_pid); 63 break; 64 } 65 return (0); 66 } 67 68 vdoualarm(arg) 69 int arg; 70 { 71 register struct proc *p; 72 73 p = pfind(arg); 74 if (p) 75 psignal(p, 16); 76 nvualarm--; 77 } 78 #endif 79 80 #include <machine/cpu.h> 81 82 /* XXX should be in an include file somewhere */ 83 #define CC_PURGE 1 84 #define CC_FLUSH 2 85 #define CC_IPURGE 4 86 #define CC_EXTPURGE 0x80000000 87 /* XXX end should be */ 88 89 /* 90 * Note that what we do here for a 68040 is different than HP-UX. 91 * 92 * In 'pux they either act on a line (len == 16), a page (len == NBPG) 93 * or the whole cache (len == anything else). 94 * 95 * In BSD we attempt to be more optimal when acting on "odd" sizes. 96 * For lengths up to 1024 we do all affected lines, up to 2*NBPG we 97 * do pages, above that we do the entire cache. 98 */ 99 /*ARGSUSED1*/ 100 cachectl(req, addr, len) 101 int req; 102 caddr_t addr; 103 int len; 104 { 105 int error = 0; 106 107 #if defined(HP380) 108 if (mmutype == MMU_68040) { 109 register int inc = 0; 110 int pa = 0, doall = 0; 111 caddr_t end; 112 113 if (addr == 0 || 114 (req & ~CC_EXTPURGE) != CC_PURGE && len > 2*NBPG) 115 doall = 1; 116 #ifdef HPUXCOMPAT 117 if ((curproc->p_md.md_flags & MDP_HPUX) && 118 len != 16 && len != NBPG) 119 doall = 1; 120 #endif 121 if (!doall) { 122 end = addr + len; 123 if (len <= 1024) { 124 addr = (caddr_t)((int)addr & ~0xF); 125 inc = 16; 126 } else { 127 addr = (caddr_t)((int)addr & ~PGOFSET); 128 inc = NBPG; 129 } 130 } 131 do { 132 /* 133 * Convert to physical address if needed. 134 * If translation fails, we perform operation on 135 * entire cache (XXX is this a rational thing to do?) 136 */ 137 if (!doall && 138 (pa == 0 || ((int)addr & PGOFSET) == 0)) { 139 pa = pmap_extract(&curproc->p_vmspace->vm_pmap, 140 (vm_offset_t)addr); 141 if (pa == 0) 142 doall = 1; 143 } 144 switch (req) { 145 case CC_EXTPURGE|CC_IPURGE: 146 case CC_IPURGE: 147 if (doall) { 148 DCFA(); 149 ICPA(); 150 } else if (inc == 16) { 151 DCFL(pa); 152 ICPL(pa); 153 } else if (inc == NBPG) { 154 DCFP(pa); 155 ICPP(pa); 156 } 157 break; 158 159 case CC_EXTPURGE|CC_PURGE: 160 case CC_PURGE: 161 if (doall) 162 DCFA(); /* note: flush not purge */ 163 else if (inc == 16) 164 DCPL(pa); 165 else if (inc == NBPG) 166 DCPP(pa); 167 break; 168 169 case CC_EXTPURGE|CC_FLUSH: 170 case CC_FLUSH: 171 if (doall) 172 DCFA(); 173 else if (inc == 16) 174 DCFL(pa); 175 else if (inc == NBPG) 176 DCFP(pa); 177 break; 178 179 default: 180 error = EINVAL; 181 break; 182 } 183 if (doall) 184 break; 185 pa += inc; 186 addr += inc; 187 } while (addr < end); 188 return(error); 189 } 190 #endif 191 switch (req) { 192 case CC_EXTPURGE|CC_PURGE: 193 case CC_EXTPURGE|CC_FLUSH: 194 #if defined(HP370) 195 if (ectype == EC_PHYS) 196 PCIA(); 197 /* fall into... */ 198 #endif 199 case CC_PURGE: 200 case CC_FLUSH: 201 DCIU(); 202 break; 203 case CC_EXTPURGE|CC_IPURGE: 204 #if defined(HP370) 205 if (ectype == EC_PHYS) 206 PCIA(); 207 else 208 #endif 209 DCIU(); 210 /* fall into... */ 211 case CC_IPURGE: 212 ICIA(); 213 break; 214 default: 215 error = EINVAL; 216 break; 217 } 218 return(error); 219 } 220