xref: /original-bsd/sys/hp300/hp300/sys_machdep.c (revision be1f24e8)
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.10 (Berkeley) 10/11/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 
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 
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*/
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;
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_flag & SHPUX) && len != 16 && len != NBPG)
118 			doall = 1;
119 #endif
120 		if (!doall) {
121 			end = addr + len;
122 			if (len <= 1024) {
123 				addr = (caddr_t)((int)addr & ~0xF);
124 				inc = 16;
125 			} else {
126 				addr = (caddr_t)((int)addr & ~PGOFSET);
127 				inc = NBPG;
128 			}
129 		}
130 		do {
131 			/*
132 			 * Convert to physical address if needed.
133 			 * If translation fails, we perform operation on
134 			 * entire cache (XXX is this a rational thing to do?)
135 			 */
136 			if (!doall &&
137 			    (pa == 0 || ((int)addr & PGOFSET) == 0)) {
138 				pa = pmap_extract(&curproc->p_vmspace->vm_pmap,
139 						  (vm_offset_t)addr);
140 				if (pa == 0)
141 					doall = 1;
142 			}
143 			switch (req) {
144 			case CC_EXTPURGE|CC_IPURGE:
145 			case CC_IPURGE:
146 				if (doall) {
147 					DCFA();
148 					ICPA();
149 				} else if (inc == 16) {
150 					DCFL(pa);
151 					ICPL(pa);
152 				} else if (inc == NBPG) {
153 					DCFP(pa);
154 					ICPP(pa);
155 				}
156 				break;
157 
158 			case CC_EXTPURGE|CC_PURGE:
159 			case CC_PURGE:
160 				if (doall)
161 					DCFA();	/* note: flush not purge */
162 				else if (inc == 16)
163 					DCPL(pa);
164 				else if (inc == NBPG)
165 					DCPP(pa);
166 				break;
167 
168 			case CC_EXTPURGE|CC_FLUSH:
169 			case CC_FLUSH:
170 				if (doall)
171 					DCFA();
172 				else if (inc == 16)
173 					DCFL(pa);
174 				else if (inc == NBPG)
175 					DCFP(pa);
176 				break;
177 
178 			default:
179 				error = EINVAL;
180 				break;
181 			}
182 			if (doall)
183 				break;
184 			pa += inc;
185 			addr += inc;
186 		} while (addr < end);
187 		return(error);
188 	}
189 #endif
190 	switch (req) {
191 	case CC_EXTPURGE|CC_PURGE:
192 	case CC_EXTPURGE|CC_FLUSH:
193 #if defined(HP370)
194 		if (ectype == EC_PHYS)
195 			PCIA();
196 		/* fall into... */
197 #endif
198 	case CC_PURGE:
199 	case CC_FLUSH:
200 		DCIU();
201 		break;
202 	case CC_EXTPURGE|CC_IPURGE:
203 #if defined(HP370)
204 		if (ectype == EC_PHYS)
205 			PCIA();
206 		else
207 #endif
208 		DCIU();
209 		/* fall into... */
210 	case CC_IPURGE:
211 		ICIA();
212 		break;
213 	default:
214 		error = EINVAL;
215 		break;
216 	}
217 	return(error);
218 }
219