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