xref: /original-bsd/sys/hp300/hp300/sys_machdep.c (revision 403c148d)
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