Subject: Tim's multiple chunk changes for -current
To: None <amiga-dev@sun-lamp.cs.berkeley.edu>
From: Niklas Hallqvist <niklas@appli.se>
List: amiga-dev
Date: 08/11/1994 00:15:40
OK, here's the diff I promised.  Note however it isn't absolutely current as
I'm not currently tracking current.  I believe it's quite easy to merge anyway
as not much has happened in these parts from what I can remember.

Niklas

===================================================================
RCS file: /home2/CVSROOT/NetBSD/sys/arch/amiga/include/pmap.h,v
retrieving revision 1.1.1.6
diff -c -r1.1.1.6 pmap.h
*** 1.1.1.6	1994/06/12 21:19:57
--- pmap.h	1994/07/11 12:44:00
***************
*** 36,42 ****
   * SUCH DAMAGE.
   *
   *	@(#)pmap.h	7.6 (Berkeley) 5/10/91
!  *	$Id: pmap.h,v 1.1.1.6 1994/06/12 21:19:57 root Exp $
   */
  #ifndef	_MACHINE_PMAP_H_
  #define	_MACHINE_PMAP_H_
--- 36,42 ----
   * SUCH DAMAGE.
   *
   *	@(#)pmap.h	7.6 (Berkeley) 5/10/91
!  *	$Id: pmap.h,v 1.1.1.1.2.6 1994/07/11 12:44:00 root Exp $
   */
  #ifndef	_MACHINE_PMAP_H_
  #define	_MACHINE_PMAP_H_
***************
*** 95,101 ****
--- 95,105 ----
  u_int		*Sysmap;
  char		*vmmap;		/* map for mem, dumps, etc. */
  
+ #ifdef MACHINE_NONCONTIG
+ #define pa_index		pmap_page_index
+ #else
  #define pa_index(pa)		atop(pa - vm_first_phys)
+ #endif
  #define pa_to_pvh(pa)		(&pv_table[pa_index(pa)])
  #define	pmap_resident_count(pmap)	((pmap)->pm_stats.resident_count)
  #endif	KERNEL
===================================================================
RCS file: /home2/CVSROOT/NetBSD/sys/arch/amiga/amiga/pmap.c,v
retrieving revision 1.1.1.10
diff -c -r1.1.1.10 pmap.c
*** 1.1.1.10	1994/06/21 23:56:03
--- pmap.c	1994/07/11 12:43:13
***************
*** 35,41 ****
   * SUCH DAMAGE.
   *
   *	@(#)pmap.c	7.5 (Berkeley) 5/10/91
!  *	$Id: pmap.c,v 1.1.1.10 1994/06/21 23:56:03 root Exp $
   */
  
  /*
--- 35,41 ----
   * SUCH DAMAGE.
   *
   *	@(#)pmap.c	7.5 (Berkeley) 5/10/91
!  *	$Id: pmap.c,v 1.1.1.1.2.10 1994/07/11 12:43:13 root Exp $
   */
  
  /*
***************
*** 144,149 ****
--- 144,165 ----
  int pmapdebug = PDB_PARANOIA;
  #endif
  
+ #ifdef MACHINE_NONCONTIG
+ #include "memlist.h"
+ 
+ /*
+  * contiguous chunk management
+  */
+ #define MAX_CHUNKS  16    /* max supported chunks of contiguous memory */
+ struct {
+         vm_offset_t start, end;
+         unsigned int first_page, pages;
+ } chunk[MAX_CHUNKS];
+ int current_chunk = 0;
+ int num_chunks;
+ vm_offset_t chunk_pos;
+ #endif /* MACHINE_NONCONTIG */
+ 
  /*
   * Get STEs and PTEs for user/kernel address space
   */
***************
*** 250,255 ****
--- 266,276 ----
  	extern vm_offset_t maxmem, physmem;
  	vm_offset_t va;
  	u_int *pte;
+ #ifdef MACHINE_NONCONTIG
+ 	extern struct boot_memlist *memlist;
+ 	extern z2mem_start, z2mem_end;
+ 	int i, page;
+ #endif
  
  	avail_start = firstaddr;
  	avail_end = maxmem << PGSHIFT;
***************
*** 257,262 ****
--- 278,318 ----
  	/* XXX: allow for msgbuf */
  	avail_end -= amiga_round_page(sizeof(struct msgbuf));
  
+ #ifdef MACHINE_NONCONTIG
+         for(i=0, num_chunks=0, page=0;
+                 i<memlist->m_nseg && i<MAX_CHUNKS; i++) {
+           if((memlist->m_seg[i].ms_attrib & MEMF_CHIP) != MEMF_CHIP) {
+             chunk[num_chunks].start = memlist->m_seg[i].ms_start;
+             chunk[num_chunks].end = chunk[num_chunks].start +
+                                      memlist->m_seg[i].ms_size;
+             chunk[num_chunks].first_page = page;
+ 
+ 	    /*
+ 	     * check for special chunks 
+ 	     * like boot chunk and zorroII mem 
+ 	     * and account for any stolen memory
+ 	     */
+ 	    if(avail_start >= chunk[num_chunks].start &&
+ 	       avail_start < chunk[num_chunks].end) {
+ 	      chunk[num_chunks].start = avail_start;
+ 	      chunk[num_chunks].end = avail_end; 
+ 	    }
+ 	    if(z2mem_end && z2mem_end >= chunk[num_chunks].start &&
+ 	       z2mem_end < chunk[num_chunks].end) {
+ 	      chunk[num_chunks].start = z2mem_start;
+ 	      chunk[num_chunks].end = z2mem_end; 
+ 	    }
+ 	    chunk[num_chunks].pages = 
+                   atop(chunk[num_chunks].end - chunk[num_chunks].start);
+             page += chunk[num_chunks].pages;
+             num_chunks++;
+           }
+         }
+ 	chunk_pos = chunk[0].start;
+ 	current_chunk = 0;
+ 	physmem = page;
+ #endif
+ 
  	mem_size = physmem << PGSHIFT;
  	virtual_avail = VM_MIN_KERNEL_ADDRESS + (firstaddr - loadaddr);
  	virtual_end = VM_MAX_KERNEL_ADDRESS;
***************
*** 338,343 ****
--- 394,449 ----
  	return((void *) val);
  }
  
+ #ifdef MACHINE_NONCONTIG
+ /*
+  * number of pages left (unallocated)
+  */
+ unsigned int
+ pmap_free_pages()
+ {
+   int i, x;
+ 
+   if(current_chunk >= num_chunks)
+    return(0);
+ 
+   /* pages in current chunk */
+   x = atop(chunk[current_chunk].end - chunk_pos);
+ 
+   /* pages in remaining chunks */
+   for(i=current_chunk+1; i<num_chunks; i++)
+     x += chunk[i].pages;
+   return(x);
+ }
+ 
+ /*
+  * return the next available page upon request
+  * if no pages left return FALSE
+  */
+ boolean_t
+ pmap_next_page(addrp)
+ vm_offset_t *addrp;
+ {
+   if(current_chunk >= num_chunks)
+     return(FALSE);
+   *addrp = chunk_pos;
+   chunk_pos += PAGE_SIZE;
+   if(chunk_pos >= chunk[current_chunk].end) {
+     current_chunk++;
+     if(current_chunk < num_chunks)
+       chunk_pos = chunk[current_chunk].start;
+   }
+   return(TRUE);
+ }
+ 
+ void
+ pmap_virtual_space(startp, endp)
+ vm_offset_t *startp;
+ vm_offset_t *endp;
+ {
+     *startp = virtual_avail;
+     *endp = virtual_end;
+ }
+ #endif
  
  /*
   *	Initialize the pmap module.
***************
*** 345,352 ****
--- 451,462 ----
   *	system needs to map virtual memory.
   */
  void
+ #ifdef MACHINE_NONCONTIG
+ pmap_init()
+ #else
  pmap_init(phys_start, phys_end)
  	vm_offset_t	phys_start, phys_end;
+ #endif
  {
  	extern vm_offset_t amigahwaddr;
  	extern u_int namigahwpg;
***************
*** 354,364 ****
--- 464,489 ----
  	vm_offset_t	addr, addr2;
  	vm_size_t	npg, s;
  	int		rv;
+ #ifdef MACHINE_NONCONTIG
+ 	int		i, size;
+ 
+ 	for(i=0, size=0; i<num_chunks; i++) {
+ 	  printf("chunk %d  %x-%x   %d bytes\n", i,
+                  chunk[i].start, chunk[i].end, 
+                  chunk[i].end - chunk[i].start);
+ 	  size += chunk[i].end - chunk[i].start;
+ 	}
+ 	printf("Total of %d bytes\n", size);
+ #endif
  
  #ifdef DEBUG
  	if (pmapdebug & PDB_FOLLOW)
+ #ifdef MACHINE_NONCONTIG
+ 		printf("pmap_init()\n");
+ #else
  		printf("pmap_init(%x, %x)\n", phys_start, phys_end);
  #endif
+ #endif
  	/*
  	 * Now that kernel map has been allocated, we can mark as
  	 * unavailable regions which we have mapped in locore.
***************
*** 401,407 ****
--- 526,537 ----
  	 * Allocate memory for random pmap data structures.  Includes the
  	 * initial segment table, pv_head_table and pmap_attributes.
  	 */
+ #ifdef MACHINE_NONCONTIG
+ 	for(i=0, npg=0; i<num_chunks; i++)
+ 	  npg += chunk[i].pages;
+ #else
  	npg = atop(phys_end - phys_start);
+ #endif
  #ifdef M68040
  	if (cpu040)
  		s = (vm_size_t)AMIGA_040STSIZE * 128 + 
***************
*** 496,506 ****
--- 626,676 ----
  	/*
  	 * Now it is safe to enable pv_table recording.
  	 */
+ #ifndef MACHINE_NONCONTIG
  	vm_first_phys = phys_start;
  	vm_last_phys = phys_end;
+ #endif
  	pmap_initialized = TRUE;
  }
  
+ #ifdef MACHINE_NONCONTIG
+ /*
+  * is this an actual physical address
+  * that we manage
+  */
+ int
+ is_phys(pa)
+ vm_offset_t pa;
+ {
+   int i;
+ 
+   if(!pmap_initialized)
+     return(0);
+   for(i=0; i<num_chunks; i++) 
+     if(pa >= chunk[i].start && pa < chunk[i].end)
+       return(1);
+   return(0);
+ }
+ 
+ /*
+  * page index of a physical address
+  */
+ unsigned int
+ pmap_page_index(pa)
+ vm_offset_t pa;
+ {
+   int i;
+   
+   for(i=0; i<num_chunks; i++)
+     if(pa >= chunk[i].start & pa < chunk[i].end)
+       return( atop(pa - chunk[i].start) + chunk[i].first_page);
+   /* this should never happen */
+   panic("pmap_page_index: physical address is not in any chunk.");
+ }
+ #else
+ #define is_phys(pa)	((pa) >= vm_first_phys && (pa) < vm_last_phys)
+ #endif
+ 
  /*
   *	Used to map a range of physical addresses into kernel
   *	virtual address space.
***************
*** 767,773 ****
  		 * Remove from the PV table (raise IPL since we
  		 * may be called at interrupt time).
  		 */
! 		if (pa < vm_first_phys || pa >= vm_last_phys)
  			continue;
  		pv = pa_to_pvh(pa);
  		ste = (int *)0;
--- 937,943 ----
  		 * Remove from the PV table (raise IPL since we
  		 * may be called at interrupt time).
  		 */
! 		if (!is_phys(pa))
  			continue;
  		pv = pa_to_pvh(pa);
  		ste = (int *)0;
***************
*** 938,944 ****
  	    prot == VM_PROT_NONE && (pmapdebug & PDB_REMOVE))
  		printf("pmap_page_protect(%x, %x)\n", pa, prot);
  #endif
! 	if (pa < vm_first_phys || pa >= vm_last_phys)
  		return;
  
  	switch (prot) {
--- 1108,1114 ----
  	    prot == VM_PROT_NONE && (pmapdebug & PDB_REMOVE))
  		printf("pmap_page_protect(%x, %x)\n", pa, prot);
  #endif
! 	if (!is_phys(pa))
  		return;
  
  	switch (prot) {
***************
*** 1164,1170 ****
  	 * Note that we raise IPL while manipulating pv_table
  	 * since pmap_enter can be called at interrupt time.
  	 */
! 	if (pa >= vm_first_phys && pa < vm_last_phys) {
  		register pv_entry_t pv, npv;
  		int s;
  
--- 1334,1340 ----
  	 * Note that we raise IPL while manipulating pv_table
  	 * since pmap_enter can be called at interrupt time.
  	 */
! 	if (is_phys(pa)) {
  		register pv_entry_t pv, npv;
  		int s;
  
***************
*** 1426,1431 ****
--- 1596,1604 ----
  	register int *pte;
  	vm_offset_t kpa;
  	int s;
+ #ifdef MACHINE_NONCONTIG
+ 	int i;
+ #endif
  
  #ifdef DEBUG
  	int *ste;
***************
*** 1440,1446 ****
--- 1613,1624 ----
  	kpt_stats.collectscans++;
  #endif
  	s = splimp();
+ #ifdef MACHINE_NONCONTIG
+ 	for(i=0; i<num_chunks; i++) {
+ 	  for (pa = chunk[i].start; pa < chunk[i].end; pa += PAGE_SIZE) {
+ #else
  	for (pa = vm_first_phys; pa < vm_last_phys; pa += PAGE_SIZE) {
+ #endif
  		register struct kpt_page *kpt, **pkpt;
  
  		/*
***************
*** 1523,1528 ****
--- 1701,1709 ----
  			printf("collect: kernel PTmap at %x still valid (%x)\n",
  			       ste, *ste);
  #endif
+ #ifdef MACHINE_NONCONTIG
+ 	  }
+ #endif
  	}
  	splx(s);
  }
***************
*** 1622,1628 ****
  		if (!pmap_ste_v(pmap_ste(pmap, sva)))
  			return;
  		pa = pmap_pte_pa(pmap_pte(pmap, sva));
! 		if (pa < vm_first_phys || pa >= vm_last_phys)
  			return;
  		pv = pa_to_pvh(pa);
  		if (pv->pv_ptste == NULL)
--- 1803,1809 ----
  		if (!pmap_ste_v(pmap_ste(pmap, sva)))
  			return;
  		pa = pmap_pte_pa(pmap_pte(pmap, sva));
! 		if (!is_phys(pa))
  			return;
  		pv = pa_to_pvh(pa);
  		if (pv->pv_ptste == NULL)
***************
*** 1768,1774 ****
  	register int *pte;
  	int s;
  
! 	if (pa < vm_first_phys || pa >= vm_last_phys)
  		return(FALSE);
  
  	pv = pa_to_pvh(pa);
--- 1949,1955 ----
  	register int *pte;
  	int s;
  
! 	if (!is_phys(pa))
  		return(FALSE);
  
  	pv = pa_to_pvh(pa);
***************
*** 1816,1822 ****
  		printf("pmap_changebit(%x, %x, %s)\n",
  		       pa, bit, setem ? "set" : "clear");
  #endif
! 	if (pa < vm_first_phys || pa >= vm_last_phys)
  		return;
  
  	pv = pa_to_pvh(pa);
--- 1997,2003 ----
  		printf("pmap_changebit(%x, %x, %s)\n",
  		       pa, bit, setem ? "set" : "clear");
  #endif
! 	if (!is_phys(pa))
  		return;
  
  	pv = pa_to_pvh(pa);
===================================================================
RCS file: /home2/CVSROOT/NetBSD/sys/arch/amiga/amiga/amiga_init.c,v
retrieving revision 1.1.1.13
diff -c -r1.1.1.13 amiga_init.c
*** 1.1.1.13	1994/07/02 15:58:03
--- amiga_init.c	1994/07/11 12:42:54
***************
*** 1,7 ****
  /* Authors: Markus Wild, Bryan Ford, Niklas Hallqvist 
   *          Michael L. Hitch - initial 68040 support
   *
!  *	$Id: amiga_init.c,v 1.1.1.13 1994/07/02 15:58:03 root Exp $
   */
  #include <sys/param.h>
  #include <sys/systm.h>
--- 1,7 ----
  /* Authors: Markus Wild, Bryan Ford, Niklas Hallqvist 
   *          Michael L. Hitch - initial 68040 support
   *
!  *	$Id: amiga_init.c,v 1.1.1.1.2.14 1994/07/11 12:42:54 root Exp $
   */
  #include <sys/param.h>
  #include <sys/systm.h>
***************
*** 56,63 ****
  vm_offset_t amigahwaddr;
  u_int namigahwpg;
  
! static vm_offset_t z2mem_start;		/* XXX */
! static vm_offset_t z2mem_end;		/* XXX */
  int use_z2_mem = 1;			/* XXX */
  
  u_long boot_fphystart, boot_fphysize, boot_cphysize;
--- 56,63 ----
  vm_offset_t amigahwaddr;
  u_int namigahwpg;
  
! vm_offset_t z2mem_start;		/* XXX */
! vm_offset_t z2mem_end;		/* XXX */
  int use_z2_mem = 1;			/* XXX */
  
  u_long boot_fphystart, boot_fphysize, boot_cphysize;
***************
*** 530,536 ****
--- 530,538 ----
  	 */
  	maxmem  = pend >> PGSHIFT;
  	lowram  = fphystart >> PGSHIFT;
+ #ifndef MACHINE_NONCONTIG
  	physmem = fphysize >> PGSHIFT;
+ #endif
    
  	/*
  	 * get the pmap module in sync with reality.

------------------------------------------------------------------------------