Subject: New patch for SunOS emul and 040s
To: None <port-m68k@NetBSD.ORG>
From: Niklas Hallqvist <niklas@cvs.openbsd.org>
List: port-m68k
Date: 12/01/1995 11:25:51
OK my former patch had a slight problem, it would pass on the UNCACHE
bit over exec calls, meaning native processes could be run with some
pages uncached, leading to a slight performance loss. This new patch
fixes this problem, however adds some more MD code, to my grief. I am
working on making emulations loadable as LKMs, and code like this need
go away, not in. However we're not there yet, so in the meantime this
will suffice.
Niklas
Index: arch/amiga/include/proc.h
===================================================================
RCS file: /cvs/src/sys/arch/amiga/include/proc.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -c -r1.1 -r1.2
*** proc.h 1995/10/18 08:50:04 1.1
--- proc.h 1995/11/28 20:48:49 1.2
***************
*** 50,53 ****
--- 50,55 ----
#define MDP_STACKADJ 0x0002 /* frame SP adjusted, might have to
undo when system call returns
ERESTART. */
+ #define MDP_UNCACHE_WX 0x0004 /* The process might modify code, so
+ don't cache writeable executable pages. */
#endif /* !_MACHINE_PROC_H_ */
Index: arch/amiga/amiga/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/amiga/amiga/machdep.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -c -r1.1 -r1.2
*** machdep.c 1995/10/18 08:49:52 1.1
--- machdep.c 1995/12/01 17:47:16 1.2
***************
*** 133,138 ****
--- 133,142 ----
extern int freebufspace;
extern u_int lowram;
+ #ifdef COMPAT_SUNOS
+ extern struct emul emul_sunos;
+ #endif
+
/* used in init_main.c */
char *cpu_type = "m68k";
/* the following is used externally (sysctl_hw) */
***************
*** 416,421 ****
--- 416,432 ----
p->p_addr->u_pcb.pcb_fpregs.fpf_null = 0;
m68881_restore(&p->p_addr->u_pcb.pcb_fpregs);
#endif
+ #ifdef COMPAT_SUNOS
+ /*
+ * SunOS' ld.so does self-modifying code without knowing
+ * about the 040's cache purging needs. So we need to uncache
+ * writeable executable pages.
+ */
+ if (p->p_emul == &emul_sunos)
+ p->p_md.md_flags |= MDP_UNCACHE_WX;
+ else
+ p->p_md.md_flags &= ~MDP_UNCACHE_WX;
+ #endif
}
/*
Index: arch/amiga/amiga/pmap.c
===================================================================
RCS file: /cvs/src/sys/arch/amiga/amiga/pmap.c,v
retrieving revision 1.1
retrieving revision 1.3
diff -c -r1.1 -r1.3
*** pmap.c 1995/10/18 08:49:53 1.1
--- pmap.c 1995/11/28 20:47:34 1.3
***************
*** 1383,1391 ****
* AMIGA pages in a MACH page.
*/
#ifdef M68040
! if (mmutype == MMU_68040 && pmap == pmap_kernel() && va >= AMIGA_UPTBASE &&
! va < (AMIGA_UPTBASE + AMIGA_UPTMAXSIZE))
cacheable = FALSE; /* don't cache user page tables */
#endif
npte = (pa & PG_FRAME) | pte_prot(pmap, prot) | PG_V;
npte |= (*(int *)pte & (PG_M|PG_U));
--- 1390,1404 ----
* AMIGA pages in a MACH page.
*/
#ifdef M68040
! if (mmutype == MMU_68040 && pmap == pmap_kernel() &&
! va >= AMIGA_UPTBASE && va < (AMIGA_UPTBASE + AMIGA_UPTMAXSIZE))
cacheable = FALSE; /* don't cache user page tables */
+
+ /* Don't cache if process can't take it, like SunOS ones. */
+ if (mmutype == MMU_68040 && pmap != pmap_kernel() &&
+ (curproc->p_md.md_flags & MDP_UNCACHE_WX) &&
+ (prot & VM_PROT_EXECUTE) && (prot & VM_PROT_WRITE))
+ checkpv = cacheable = FALSE;
#endif
npte = (pa & PG_FRAME) | pte_prot(pmap, prot) | PG_V;
npte |= (*(int *)pte & (PG_M|PG_U));