Subject: MACHINE_NONCONTIG
To: None <tech-kern@NetBSD.ORG>
From: Gordon W. Ross <gwr@mc.com>
List: tech-kern
Date: 02/27/1997 17:14:00
It would be nice if we could get rid of all the 

	#ifdef MACHINE_NONCONTIG

junk in the VM code.  Here is one possible way:

The basic idea is to provide a "compatibility module" that any
port with contiguous memory could list in its "files.$ARCH" to
pull in a simple implementation of these functions:

u_int		pmap_free_pages __P((void));
boolean_t	pmap_next_page __P((vm_offset_t *));
int		pmap_page_index __P((vm_offset_t));
void		pmap_virtual_space __P((vm_offset_t *, vm_offset_t *));

Attached is a proposed implementation of those functions that
uses the traditional MACHINE_NONCONTIG global variables.  If
we drop this into, say sys/vm/pmap_contig.c then I think we
could get rid of MACHINE_NONCONTIG once and for all!

Comments?
Gordon

[ Proposed vm/pmap_contig.c below. ]

/*
 * This module is for use on machines with only contiguous
 * physical memory, and simulates the old pmap interface
 * that was used before MACHINE_NONCONTIG came and went.
 * For simplicity, this interface retains the variables
 * that were used in the old interface.  These are:
 *
 *   avail_start, avail_end:     Physical address range for VM
 *   virtual_avail, virtual_end: Virtual address range for VM
 *
 * The above four variables should be initialized before VM
 * initialiation (i.e. in pmap_bootstrap).  The variable:
 *   avail_next
 * should be initialized to avail_start in the same place.
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>

#include <vm/vm.h>
#include <vm/vm_kern.h>
#include <vm/vm_page.h>

/*
 * Address of next page to be returned by pmap_next_page()
 * Initial value should be avail_start
 */
vm_offset_t avail_next;

/*
 * Return the number of page indices in the range of
 * possible return values for pmap_page_index() for
 * all addresses provided by pmap_next_page().  This
 * return value is used to allocate per-page data.
 *
 * Note that a machine with a "hole" in physical memory
 * may include the pages in the hole in this count, and
 * skip the pages in the hole in pmap_next_page().
 */
u_int
pmap_free_pages()
{
	int bytes;

	bytes = avail_end - avail_start;
	return(atop(bytes));
}

/*
 * If there are still physical pages available, put the address of
 * the next available one at paddr and return TRUE.  Otherwise,
 * return FALSE to indicate that there are no more free pages.
 * Note that avail_next is set to avail_start in pmap_bootstrap().
 *
 * Imporant:  The page indices of the pages returned here must be
 * in ascending order.
 */
boolean_t
pmap_next_page(paddr)
	vm_offset_t *paddr;
{
	/* Any available memory remaining? */
	if (avail_next >= avail_end)
		return FALSE;

	/* Have memory, will travel... */
	*paddr = avail_next;
	avail_next += PAGE_SIZE;
	return TRUE;
}

/*
 * pmap_page_index()
 *
 * Given a physical address, return a page index.
 *
 * There can be some values that we never return (i.e. a hole)
 * as long as the range of indices returned by this function
 * is smaller than the value returned by pmap_free_pages().
 * The returned index does NOT need to start at zero.
 *
 * This should normally be a macro in pmap.h, but one might
 * want a real function here for DIAGNOSTIC checks, etc.
 */
#ifndef	pmap_page_index
int
pmap_page_index(pa)
	vm_offset_t pa;
{
	return (atop(pa));
}
#endif	/* !pmap_page_index */

/*
 * How much virtual space does this kernel have?
 * (After mapping kernel text, data, etc.)
 */
void
pmap_virtual_space(v_start, v_end)
	vm_offset_t *v_start;
	vm_offset_t *v_end;
{
	*v_start = virtual_avail;
	*v_end   = virtual_end;
}