Subject: mapped device panic (fix)
To: None <port-sun3@NetBSD.ORG>
From: Gordon W. Ross <gwr@mc.com>
List: port-sun3
Date: 11/19/1997 14:38:35
Here is the final fix (I hope).  This is what will appear in
the release, as soon as the releng people do their thing.

The correction affects any mapped-device access, i.e.
when the Xsun server maps its frame buffer.

Problem reports appreciated.  None of my machines has a "head"
at the moment, so I'm really glad someone caught this!

*** pmap-86.c	Mon Nov  3 17:47:18 1997
--- pmap-88.c	Wed Nov 19 14:27:15 1997
***************
*** 152,160 ****
   * 0xFF000000 will look like 0x1F000000 after one reads back
   * the pte and converts the PFN to a physical address.
   */
! #define MEM_BITS	(PG_TYPE | PA_PGNUM(0xF0000000))
  #define	IS_MAIN_MEM(pte) (((pte) & MEM_BITS) == 0)
  
  /*
   * Is there a Virtually Addressed Cache (VAC) alias problem
   * if one page is mapped at both a1 and a2?
--- 152,164 ----
   * 0xFF000000 will look like 0x1F000000 after one reads back
   * the pte and converts the PFN to a physical address.
   */
! #define MEM_BITS	(PG_TYPE | PA_PGNUM(0xF8000000))
  #define	IS_MAIN_MEM(pte) (((pte) & MEM_BITS) == 0)
  
+ /* Does this (pseudo) PA represent device space? */
+ #define PA_DEV_MASK   (0xF8000000 | PMAP_OBIO | PMAP_VME16)
+ #define PA_IS_DEV(pa) ((pa) & PA_DEV_MASK)
+ 
  /*
   * Is there a Virtually Addressed Cache (VAC) alias problem
   * if one page is mapped at both a1 and a2?
***************
*** 462,468 ****
  
  	idx = PA_PGNUM(pa);
  #ifdef	DIAGNOSTIC
! 	if (idx > physmem)
  		panic("pmap:pa_to_pvhead: bad pa=0x%lx", pa);
  #endif
  	return (&pv_head_tbl[idx]);
--- 466,472 ----
  
  	idx = PA_PGNUM(pa);
  #ifdef	DIAGNOSTIC
! 	if (PA_IS_DEV(pa) || (idx >= physmem))
  		panic("pmap:pa_to_pvhead: bad pa=0x%lx", pa);
  #endif
  	return (&pv_head_tbl[idx]);
***************
*** 475,482 ****
  
  	idx = PA_PGNUM(pa);
  #ifdef	DIAGNOSTIC
! 	if (idx > physmem)
! 		panic("pmap:pa_to_pvflags: idx=0x%x", idx);
  #endif
  	return (&pv_flags_tbl[idx]);
  }
--- 479,486 ----
  
  	idx = PA_PGNUM(pa);
  #ifdef	DIAGNOSTIC
! 	if (PA_IS_DEV(pa) || (idx >= physmem))
! 		panic("pmap:pa_to_pvflags: bad pa=0x%lx", pa);
  #endif
  	return (&pv_flags_tbl[idx]);
  }
***************
*** 2647,2652 ****
--- 2651,2660 ----
  	if (!pv_initialized)
  		return;
  
+ 	/* The VM code may call this on device addresses! */
+ 	if (PA_IS_DEV(pa))
+ 		return;
+ 
  	pv_flags = pa_to_pvflags(pa);
  	head     = pa_to_pvhead(pa);
  
***************
*** 2670,2675 ****
--- 2678,2687 ----
  	if (!pv_initialized)
  		return (0);
  
+ 	/* The VM code may call this on device addresses! */
+ 	if (PA_IS_DEV(pa))
+ 		return (0);
+ 
  	pv_flags = pa_to_pvflags(pa);
  	head     = pa_to_pvhead(pa);
  
***************
*** 2697,2702 ****
--- 2709,2718 ----
  	if (!pv_initialized)
  		return;
  
+ 	/* The VM code may call this on device addresses! */
+ 	if (PA_IS_DEV(pa))
+ 		return;
+ 
  	pv_flags = pa_to_pvflags(pa);
  	head     = pa_to_pvhead(pa);
  
***************
*** 2721,2726 ****
--- 2737,2746 ----
  	if (!pv_initialized)
  		return (0);
  
+ 	/* The VM code may call this on device addresses! */
+ 	if (PA_IS_DEV(pa))
+ 		return (0);
+ 
  	pv_flags = pa_to_pvflags(pa);
  	head     = pa_to_pvhead(pa);
  
***************
*** 2890,2895 ****
--- 2910,2919 ----
  {
  	int s;
  
+ 	/* The VM code may call this on device addresses! */
+ 	if (PA_IS_DEV(pa))
+ 		return;
+ 
  	s = splpmap();
  
  #ifdef PMAP_DEBUG
***************
*** 3856,3862 ****
  		return;
  	}
  	idx = PA_PGNUM(pa);
! 	if (idx > physmem) {
  		db_printf("bad address\n");
  		return;
  	}
--- 3880,3886 ----
  		return;
  	}
  	idx = PA_PGNUM(pa);
! 	if (idx >= physmem) {
  		db_printf("bad address\n");
  		return;
  	}