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