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
vdoualarm(arg)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*/
cachectl(req,addr,len)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