1 /* 2 * Copyright (c) 1982, 1986 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)sys_machdep.c 7.10 (Berkeley) 10/11/92 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; 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_flag & SHPUX) && len != 16 && len != NBPG) 118 doall = 1; 119 #endif 120 if (!doall) { 121 end = addr + len; 122 if (len <= 1024) { 123 addr = (caddr_t)((int)addr & ~0xF); 124 inc = 16; 125 } else { 126 addr = (caddr_t)((int)addr & ~PGOFSET); 127 inc = NBPG; 128 } 129 } 130 do { 131 /* 132 * Convert to physical address if needed. 133 * If translation fails, we perform operation on 134 * entire cache (XXX is this a rational thing to do?) 135 */ 136 if (!doall && 137 (pa == 0 || ((int)addr & PGOFSET) == 0)) { 138 pa = pmap_extract(&curproc->p_vmspace->vm_pmap, 139 (vm_offset_t)addr); 140 if (pa == 0) 141 doall = 1; 142 } 143 switch (req) { 144 case CC_EXTPURGE|CC_IPURGE: 145 case CC_IPURGE: 146 if (doall) { 147 DCFA(); 148 ICPA(); 149 } else if (inc == 16) { 150 DCFL(pa); 151 ICPL(pa); 152 } else if (inc == NBPG) { 153 DCFP(pa); 154 ICPP(pa); 155 } 156 break; 157 158 case CC_EXTPURGE|CC_PURGE: 159 case CC_PURGE: 160 if (doall) 161 DCFA(); /* note: flush not purge */ 162 else if (inc == 16) 163 DCPL(pa); 164 else if (inc == NBPG) 165 DCPP(pa); 166 break; 167 168 case CC_EXTPURGE|CC_FLUSH: 169 case CC_FLUSH: 170 if (doall) 171 DCFA(); 172 else if (inc == 16) 173 DCFL(pa); 174 else if (inc == NBPG) 175 DCFP(pa); 176 break; 177 178 default: 179 error = EINVAL; 180 break; 181 } 182 if (doall) 183 break; 184 pa += inc; 185 addr += inc; 186 } while (addr < end); 187 return(error); 188 } 189 #endif 190 switch (req) { 191 case CC_EXTPURGE|CC_PURGE: 192 case CC_EXTPURGE|CC_FLUSH: 193 #if defined(HP370) 194 if (ectype == EC_PHYS) 195 PCIA(); 196 /* fall into... */ 197 #endif 198 case CC_PURGE: 199 case CC_FLUSH: 200 DCIU(); 201 break; 202 case CC_EXTPURGE|CC_IPURGE: 203 #if defined(HP370) 204 if (ectype == EC_PHYS) 205 PCIA(); 206 else 207 #endif 208 DCIU(); 209 /* fall into... */ 210 case CC_IPURGE: 211 ICIA(); 212 break; 213 default: 214 error = EINVAL; 215 break; 216 } 217 return(error); 218 } 219