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