From 86a8f1d20177851815b02996e1dbbbca7d71e5f2 Mon Sep 17 00:00:00 2001 From: scottr Date: Sun, 28 Nov 1999 10:36:56 +0000 Subject: [PATCH] Sync cachectl1() implementation with other m68k ports. --- sys/arch/mac68k/include/pmap.h | 7 +- sys/arch/mac68k/mac68k/sys_machdep.c | 141 +++++++++++++++++++++++---- 2 files changed, 127 insertions(+), 21 deletions(-) diff --git a/sys/arch/mac68k/include/pmap.h b/sys/arch/mac68k/include/pmap.h index 927dc6191105..5264ba5edf5b 100644 --- a/sys/arch/mac68k/include/pmap.h +++ b/sys/arch/mac68k/include/pmap.h @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.h,v 1.26 1999/07/21 03:18:21 briggs Exp $ */ +/* $NetBSD: pmap.h,v 1.27 1999/11/28 10:36:56 scottr Exp $ */ /* * Copyright (c) 1987 Carnegie-Mellon University @@ -185,8 +185,9 @@ extern pt_entry_t *Sysmap; extern char *vmmap; /* map for mem, dumps, etc. */ /* pmap.c */ -vaddr_t pmap_map __P((vaddr_t, paddr_t, paddr_t, int)); -void pmap_procwr __P((struct proc *, vaddr_t, u_long)); +vaddr_t pmap_map __P((vaddr_t, paddr_t, paddr_t, int)); +void pmap_procwr __P((struct proc *, vaddr_t, u_long)); +#define PMAP_NEED_PROCWR #endif /* _KERNEL */ diff --git a/sys/arch/mac68k/mac68k/sys_machdep.c b/sys/arch/mac68k/mac68k/sys_machdep.c index 5b80a93157d8..0f873f140d0e 100644 --- a/sys/arch/mac68k/mac68k/sys_machdep.c +++ b/sys/arch/mac68k/mac68k/sys_machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: sys_machdep.c,v 1.13 1999/02/26 22:37:58 is Exp $ */ +/* $NetBSD: sys_machdep.c,v 1.14 1999/11/28 10:36:57 scottr Exp $ */ /* * Copyright (c) 1990 The Regents of the University of California. @@ -81,58 +81,62 @@ #include #include +#include + #include #ifdef TRACE int nvualarm; -vtrace(p, v, retval) +sys_vtrace(p, v, retval) struct proc *p; void *v; register_t *retval; { - register struct vtrace_args /* { + struct sys_vtrace_args /* { syscallarg(int) request; syscallarg(int) value; } */ *uap = v; int vdoualarm(); - switch (uap->request) { + switch (SCARG(uap, request)) { case VTR_DISABLE: /* disable a trace point */ case VTR_ENABLE: /* enable a trace point */ - if (uap->value < 0 || uap->value >= TR_NFLAGS) + if (SCARG(uap, value) < 0 || SCARG(uap, value) >= TR_NFLAGS) return (EINVAL); - *retval = traceflags[uap->value]; - traceflags[uap->value] = uap->request; + *retval = traceflags[SCARG(uap, value)]; + traceflags[SCARG(uap, value)] = SCARG(uap, request); break; case VTR_VALUE: /* return a trace point setting */ - if (uap->value < 0 || uap->value >= TR_NFLAGS) + if (SCARG(uap, value) < 0 || SCARG(uap, value) >= TR_NFLAGS) return (EINVAL); - *retval = traceflags[uap->value]; + *retval = traceflags[SCARG(uap, value)]; break; case VTR_UALARM: /* set a real-time ualarm, less than 1 min */ - if (uap->value <= 0 || uap->value > 60 * hz || nvualarm > 5) + if (SCARG(uap, value) <= 0 || SCARG(uap, value) > 60 * hz || + nvualarm > 5) return (EINVAL); nvualarm++; - timeout(vdoualarm, (caddr_t)p->p_pid, uap->value); + timeout(vdoualarm, (void *)p->p_pid, SCARG(uap, value)); break; case VTR_STAMP: - trace(TR_STAMP, uap->value, p->p_pid); + trace(TR_STAMP, SCARG(uap, value), p->p_pid); break; } return (0); } vdoualarm(arg) - int arg; + void *arg; { - register struct proc *p; + int pid = (int)arg; + struct proc *p; - p = pfind(arg); + p = pfind(pid); if (p) psignal(p, 16); nvualarm--; @@ -148,9 +152,16 @@ vdoualarm(arg) #define CC_EXTPURGE 0x80000000 /* XXX end should be */ -void DCIU __P((void)); -void ICIA __P((void)); - +/* + * Note that what we do here for a 68040 is different than HP-UX. + * + * In 'pux they either act on a line (len == 16), a page (len == NBPG) + * or the whole cache (len == anything else). + * + * In BSD we attempt to be more optimal when acting on "odd" sizes. + * For lengths up to 1024 we do all affected lines, up to 2*NBPG we + * do pages, above that we do the entire cache. + */ /*ARGSUSED1*/ int cachectl1(req, addr, len, p) @@ -161,6 +172,100 @@ cachectl1(req, addr, len, p) { int error = 0; +#if defined(M68040) || defined(M68060) + if (mmutype == MMU_68040) { + int inc = 0; + int doall = 0; + paddr_t pa = 0; + vaddr_t end = 0; +#ifdef COMPAT_HPUX + extern struct emul emul_hpux; + + if ((p->p_emul == &emul_hpux) && + len != 16 && len != NBPG) + doall = 1; +#endif + + if (addr == 0 || +#if defined(M68040) +#if defined(M68060) + (cputype == CPU_68040 && req & CC_IPURGE) || +#else + (req && CC_IPURGE) || +#endif +#endif + ((req & ~CC_EXTPURGE) != CC_PURGE && len > 2*NBPG)) + doall = 1; + + if (!doall) { + end = addr + len; + if (len <= 1024) { + addr = addr & ~0xF; + inc = 16; + } else { + addr = addr & ~PGOFSET; + inc = NBPG; + } + } + do { + /* + * Convert to physical address if needed. + * If translation fails, we perform operation on + * entire cache (XXX is this a rational thing to do?) + */ + if (!doall && + (pa == 0 || ((int)addr & PGOFSET) == 0)) { + if (pmap_extract(p->p_vmspace->vm_map.pmap, + addr, &pa) == FALSE) + doall = 1; + } + switch (req) { + case CC_EXTPURGE|CC_IPURGE: + case CC_IPURGE: + if (doall) { + DCFA(); + ICPA(); + } else if (inc == 16) { + DCFL(pa); + ICPL(pa); + } else if (inc == NBPG) { + DCFP(pa); + ICPP(pa); + } + break; + + case CC_EXTPURGE|CC_PURGE: + case CC_PURGE: + if (doall) + DCFA(); /* note: flush not purge */ + else if (inc == 16) + DCPL(pa); + else if (inc == NBPG) + DCPP(pa); + break; + + case CC_EXTPURGE|CC_FLUSH: + case CC_FLUSH: + if (doall) + DCFA(); + else if (inc == 16) + DCFL(pa); + else if (inc == NBPG) + DCFP(pa); + break; + + default: + error = EINVAL; + break; + } + if (doall) + break; + pa += inc; + addr += inc; + } while (addr < end); + return(error); + } +#endif switch (req) { case CC_EXTPURGE|CC_PURGE: case CC_EXTPURGE|CC_FLUSH: