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