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