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));