xref: /original-bsd/sys/hp300/hp300/sys_machdep.c (revision 2a74b1be)
185e7c9a4Smckusick /*
24975c9eaSbostic  * Copyright (c) 1982, 1986, 1993
34975c9eaSbostic  *	The Regents of the University of California.  All rights reserved.
485e7c9a4Smckusick  *
585e7c9a4Smckusick  * %sccs.include.redist.c%
685e7c9a4Smckusick  *
7*2a74b1beShibler  *	@(#)sys_machdep.c	8.2 (Berkeley) 01/13/94
885e7c9a4Smckusick  */
985e7c9a4Smckusick 
104e6f2c04Sbostic #include <sys/param.h>
114e6f2c04Sbostic #include <sys/systm.h>
124e6f2c04Sbostic #include <sys/ioctl.h>
134e6f2c04Sbostic #include <sys/file.h>
144e6f2c04Sbostic #include <sys/time.h>
154e6f2c04Sbostic #include <sys/proc.h>
164e6f2c04Sbostic #include <sys/uio.h>
174e6f2c04Sbostic #include <sys/kernel.h>
184e6f2c04Sbostic #include <sys/mtio.h>
194e6f2c04Sbostic #include <sys/buf.h>
204e6f2c04Sbostic #include <sys/trace.h>
214e6f2c04Sbostic 
224e6f2c04Sbostic #include <vm/vm.h>
2385e7c9a4Smckusick 
2485e7c9a4Smckusick #ifdef TRACE
2585e7c9a4Smckusick int	nvualarm;
2685e7c9a4Smckusick 
27bf88622fStorek struct vtrace_args {
2885e7c9a4Smckusick 	int	request;
2985e7c9a4Smckusick 	int	value;
30bf88622fStorek };
31bf88622fStorek vtrace(p, uap, retval)
32bf88622fStorek 	struct proc *p;
33bf88622fStorek 	register struct vtrace_args *uap;
341af7d2d2Smckusick 	int *retval;
351af7d2d2Smckusick {
3685e7c9a4Smckusick 	int vdoualarm();
3785e7c9a4Smckusick 
3885e7c9a4Smckusick 	switch (uap->request) {
3985e7c9a4Smckusick 
4085e7c9a4Smckusick 	case VTR_DISABLE:		/* disable a trace point */
4185e7c9a4Smckusick 	case VTR_ENABLE:		/* enable a trace point */
4285e7c9a4Smckusick 		if (uap->value < 0 || uap->value >= TR_NFLAGS)
430e839d83Skarels 			return (EINVAL);
441af7d2d2Smckusick 		*retval = traceflags[uap->value];
4585e7c9a4Smckusick 		traceflags[uap->value] = uap->request;
4685e7c9a4Smckusick 		break;
4785e7c9a4Smckusick 
4885e7c9a4Smckusick 	case VTR_VALUE:		/* return a trace point setting */
4985e7c9a4Smckusick 		if (uap->value < 0 || uap->value >= TR_NFLAGS)
500e839d83Skarels 			return (EINVAL);
511af7d2d2Smckusick 		*retval = traceflags[uap->value];
5285e7c9a4Smckusick 		break;
5385e7c9a4Smckusick 
5485e7c9a4Smckusick 	case VTR_UALARM:	/* set a real-time ualarm, less than 1 min */
551af7d2d2Smckusick 		if (uap->value <= 0 || uap->value > 60 * hz || nvualarm > 5)
560e839d83Skarels 			return (EINVAL);
5785e7c9a4Smckusick 		nvualarm++;
581af7d2d2Smckusick 		timeout(vdoualarm, (caddr_t)p->p_pid, uap->value);
5985e7c9a4Smckusick 		break;
6085e7c9a4Smckusick 
6185e7c9a4Smckusick 	case VTR_STAMP:
621af7d2d2Smckusick 		trace(TR_STAMP, uap->value, p->p_pid);
6385e7c9a4Smckusick 		break;
6485e7c9a4Smckusick 	}
650e839d83Skarels 	return (0);
6685e7c9a4Smckusick }
6785e7c9a4Smckusick 
vdoualarm(arg)6885e7c9a4Smckusick vdoualarm(arg)
6985e7c9a4Smckusick 	int arg;
7085e7c9a4Smckusick {
7185e7c9a4Smckusick 	register struct proc *p;
7285e7c9a4Smckusick 
7385e7c9a4Smckusick 	p = pfind(arg);
7485e7c9a4Smckusick 	if (p)
7585e7c9a4Smckusick 		psignal(p, 16);
7685e7c9a4Smckusick 	nvualarm--;
7785e7c9a4Smckusick }
7885e7c9a4Smckusick #endif
7953286c58Shibler 
804e6f2c04Sbostic #include <machine/cpu.h>
8153286c58Shibler 
8253286c58Shibler /* XXX should be in an include file somewhere */
8353286c58Shibler #define CC_PURGE	1
8453286c58Shibler #define CC_FLUSH	2
8553286c58Shibler #define CC_IPURGE	4
8653286c58Shibler #define CC_EXTPURGE	0x80000000
8753286c58Shibler /* XXX end should be */
8853286c58Shibler 
8914b153a2Shibler /*
9014b153a2Shibler  * Note that what we do here for a 68040 is different than HP-UX.
9114b153a2Shibler  *
9214b153a2Shibler  * In 'pux they either act on a line (len == 16), a page (len == NBPG)
9314b153a2Shibler  * or the whole cache (len == anything else).
9414b153a2Shibler  *
9514b153a2Shibler  * In BSD we attempt to be more optimal when acting on "odd" sizes.
9614b153a2Shibler  * For lengths up to 1024 we do all affected lines, up to 2*NBPG we
9714b153a2Shibler  * do pages, above that we do the entire cache.
9814b153a2Shibler  */
9953286c58Shibler /*ARGSUSED1*/
cachectl(req,addr,len)10053286c58Shibler cachectl(req, addr, len)
10153286c58Shibler 	int req;
10253286c58Shibler 	caddr_t	addr;
10353286c58Shibler 	int len;
10453286c58Shibler {
10553286c58Shibler 	int error = 0;
10653286c58Shibler 
10714b153a2Shibler #if defined(HP380)
10814b153a2Shibler 	if (mmutype == MMU_68040) {
109*2a74b1beShibler 		register int inc = 0;
11014b153a2Shibler 		int pa = 0, doall = 0;
11114b153a2Shibler 		caddr_t end;
11214b153a2Shibler 
11314b153a2Shibler 		if (addr == 0 ||
11414b153a2Shibler 		    (req & ~CC_EXTPURGE) != CC_PURGE && len > 2*NBPG)
11514b153a2Shibler 			doall = 1;
11614b153a2Shibler #ifdef HPUXCOMPAT
1176b3fa1f1Shibler 		if ((curproc->p_md.md_flags & MDP_HPUX) &&
1186b3fa1f1Shibler 		    len != 16 && len != NBPG)
11914b153a2Shibler 			doall = 1;
12014b153a2Shibler #endif
12114b153a2Shibler 		if (!doall) {
12214b153a2Shibler 			end = addr + len;
12314b153a2Shibler 			if (len <= 1024) {
12414b153a2Shibler 				addr = (caddr_t)((int)addr & ~0xF);
12514b153a2Shibler 				inc = 16;
12614b153a2Shibler 			} else {
12714b153a2Shibler 				addr = (caddr_t)((int)addr & ~PGOFSET);
12814b153a2Shibler 				inc = NBPG;
12914b153a2Shibler 			}
13014b153a2Shibler 		}
13114b153a2Shibler 		do {
13214b153a2Shibler 			/*
13314b153a2Shibler 			 * Convert to physical address if needed.
13414b153a2Shibler 			 * If translation fails, we perform operation on
13514b153a2Shibler 			 * entire cache (XXX is this a rational thing to do?)
13614b153a2Shibler 			 */
13714b153a2Shibler 			if (!doall &&
13814b153a2Shibler 			    (pa == 0 || ((int)addr & PGOFSET) == 0)) {
13914b153a2Shibler 				pa = pmap_extract(&curproc->p_vmspace->vm_pmap,
14014b153a2Shibler 						  (vm_offset_t)addr);
14114b153a2Shibler 				if (pa == 0)
14214b153a2Shibler 					doall = 1;
14314b153a2Shibler 			}
14414b153a2Shibler 			switch (req) {
14514b153a2Shibler 			case CC_EXTPURGE|CC_IPURGE:
14614b153a2Shibler 			case CC_IPURGE:
14714b153a2Shibler 				if (doall) {
14814b153a2Shibler 					DCFA();
14914b153a2Shibler 					ICPA();
15014b153a2Shibler 				} else if (inc == 16) {
15114b153a2Shibler 					DCFL(pa);
15214b153a2Shibler 					ICPL(pa);
15314b153a2Shibler 				} else if (inc == NBPG) {
15414b153a2Shibler 					DCFP(pa);
15514b153a2Shibler 					ICPP(pa);
15614b153a2Shibler 				}
15714b153a2Shibler 				break;
15814b153a2Shibler 
15914b153a2Shibler 			case CC_EXTPURGE|CC_PURGE:
16014b153a2Shibler 			case CC_PURGE:
16114b153a2Shibler 				if (doall)
16214b153a2Shibler 					DCFA();	/* note: flush not purge */
16314b153a2Shibler 				else if (inc == 16)
16414b153a2Shibler 					DCPL(pa);
16514b153a2Shibler 				else if (inc == NBPG)
16614b153a2Shibler 					DCPP(pa);
16714b153a2Shibler 				break;
16814b153a2Shibler 
16914b153a2Shibler 			case CC_EXTPURGE|CC_FLUSH:
17014b153a2Shibler 			case CC_FLUSH:
17114b153a2Shibler 				if (doall)
17214b153a2Shibler 					DCFA();
17314b153a2Shibler 				else if (inc == 16)
17414b153a2Shibler 					DCFL(pa);
17514b153a2Shibler 				else if (inc == NBPG)
17614b153a2Shibler 					DCFP(pa);
17714b153a2Shibler 				break;
17814b153a2Shibler 
17914b153a2Shibler 			default:
18014b153a2Shibler 				error = EINVAL;
18114b153a2Shibler 				break;
18214b153a2Shibler 			}
18314b153a2Shibler 			if (doall)
18414b153a2Shibler 				break;
18514b153a2Shibler 			pa += inc;
18614b153a2Shibler 			addr += inc;
18714b153a2Shibler 		} while (addr < end);
18814b153a2Shibler 		return(error);
18914b153a2Shibler 	}
19014b153a2Shibler #endif
19153286c58Shibler 	switch (req) {
19253286c58Shibler 	case CC_EXTPURGE|CC_PURGE:
19353286c58Shibler 	case CC_EXTPURGE|CC_FLUSH:
19453286c58Shibler #if defined(HP370)
19553286c58Shibler 		if (ectype == EC_PHYS)
19653286c58Shibler 			PCIA();
19753286c58Shibler 		/* fall into... */
19853286c58Shibler #endif
19953286c58Shibler 	case CC_PURGE:
20053286c58Shibler 	case CC_FLUSH:
20153286c58Shibler 		DCIU();
20253286c58Shibler 		break;
20353286c58Shibler 	case CC_EXTPURGE|CC_IPURGE:
20453286c58Shibler #if defined(HP370)
20553286c58Shibler 		if (ectype == EC_PHYS)
20653286c58Shibler 			PCIA();
20753286c58Shibler 		else
20853286c58Shibler #endif
20953286c58Shibler 		DCIU();
21053286c58Shibler 		/* fall into... */
21153286c58Shibler 	case CC_IPURGE:
21253286c58Shibler 		ICIA();
21353286c58Shibler 		break;
21453286c58Shibler 	default:
21553286c58Shibler 		error = EINVAL;
21653286c58Shibler 		break;
21753286c58Shibler 	}
21853286c58Shibler 	return(error);
21953286c58Shibler }
220