xref: /illumos-gate/usr/src/psm/stand/boot/sparc/common/sun4x_standalloc.c (revision a2cd9e1884647e1e412c282879881873b71c84df)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5986fd29aSsetje  * Common Development and Distribution License (the "License").
6986fd29aSsetje  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22986fd29aSsetje  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #include <sys/types.h>
277c478bd9Sstevel@tonic-gate #include <sys/saio.h>
287c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h>
297c478bd9Sstevel@tonic-gate #include <sys/promif.h>
307c478bd9Sstevel@tonic-gate #include <sys/bootconf.h>
317c478bd9Sstevel@tonic-gate #include <sys/salib.h>
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate #define	NIL		0
347c478bd9Sstevel@tonic-gate 
357c478bd9Sstevel@tonic-gate #ifdef DEBUG
367c478bd9Sstevel@tonic-gate static int	resalloc_debug = 1;
377c478bd9Sstevel@tonic-gate #else /* DEBUG */
387c478bd9Sstevel@tonic-gate static int	resalloc_debug = 0;
397c478bd9Sstevel@tonic-gate #endif /* DEBUG */
407c478bd9Sstevel@tonic-gate #define	dprintf	if (resalloc_debug) printf
417c478bd9Sstevel@tonic-gate 
427c478bd9Sstevel@tonic-gate extern struct memlist	*vfreelistp, *pfreelistp;
437c478bd9Sstevel@tonic-gate extern	void		reset_alloc(void);
447c478bd9Sstevel@tonic-gate extern	void		alloc_segment(caddr_t);
457c478bd9Sstevel@tonic-gate 
46*a2cd9e18SToomas Soome extern caddr_t		memlistpage;
477c478bd9Sstevel@tonic-gate caddr_t		le_page;
487c478bd9Sstevel@tonic-gate caddr_t		ie_page;
497c478bd9Sstevel@tonic-gate caddr_t		scratchmemp;
507c478bd9Sstevel@tonic-gate extern int	pagesize;
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate #define	N_FREELIST	20	/* keep the largest 20 free regions */
537c478bd9Sstevel@tonic-gate static size_t	free_size[N_FREELIST];
547c478bd9Sstevel@tonic-gate static caddr_t	free_addr[N_FREELIST];
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate /*
577c478bd9Sstevel@tonic-gate  * OBP sets up a 1:1 mapping of virtual to physical in the range 8KB-10MB.  The
587c478bd9Sstevel@tonic-gate  * standalone is free to use any or all of this during its lifetime.
597c478bd9Sstevel@tonic-gate  * Unfortunately, some platforms (Serengeti and LW8) can't use the full range.
607c478bd9Sstevel@tonic-gate  * See 4799331 for more details.  Limited platforms can use up to
617c478bd9Sstevel@tonic-gate  * MAPPEDMEM_MINTOP; everyone else can use up to MAPPEDMEM_FULLTOP.
627c478bd9Sstevel@tonic-gate  * resalloc_init makes the determination as to how much the machine being booted
637c478bd9Sstevel@tonic-gate  * can use.
647c478bd9Sstevel@tonic-gate  *
657c478bd9Sstevel@tonic-gate  * But wait!  There's more!  resalloc handles three types of allocations: Two
667c478bd9Sstevel@tonic-gate  * flavors of RES_BOOTSCRATCH (RES_BOOTSCRATCH and RES_BOOTSCRATCH_NOFAIL), and
677c478bd9Sstevel@tonic-gate  * one of RES_CHILDVIRT.  RES_CHILDVIRT is handled by prom_alloc, and is boring.
687c478bd9Sstevel@tonic-gate  * We handle RES_BOOTSCRATCH allocations ourselves using the portion of the 1:1
697c478bd9Sstevel@tonic-gate  * range not consumed by boot.  The unconsumed range is subdivided into two
707c478bd9Sstevel@tonic-gate  * portions - the general area from top_resvmem to top_bootmem and the reserved
717c478bd9Sstevel@tonic-gate  * area from above memlistpage to top_resvmem.  Both RES_BOOTSCRATCH flavors are
727c478bd9Sstevel@tonic-gate  * satisfied by the general area until said area is exhausted, at which point
737c478bd9Sstevel@tonic-gate  * RES_BOOTSCRATCH allocations return failure.  RES_BOOTSCRATCH_NOFAIL
747c478bd9Sstevel@tonic-gate  * allocations can't fail, so we'll try to satisfy them from the reserved area
757c478bd9Sstevel@tonic-gate  * if the general area is full.  If we still can't satisfy the nofail
767c478bd9Sstevel@tonic-gate  * allocation, we'll call prom_panic.
777c478bd9Sstevel@tonic-gate  *
787c478bd9Sstevel@tonic-gate  * This whole boot memory allocation thing needs some serious rethinking.
797c478bd9Sstevel@tonic-gate  *
807c478bd9Sstevel@tonic-gate  * Memory layout:
817c478bd9Sstevel@tonic-gate  *
827c478bd9Sstevel@tonic-gate  *	|-------| top_bootmem
837c478bd9Sstevel@tonic-gate  *	|	| } MAPPEDMEM_FULLTOP (only on non-serengeti, lw8)
847c478bd9Sstevel@tonic-gate  *	|	| } MAPPEDMEM_MINTOP
857c478bd9Sstevel@tonic-gate  *	|-------| top_resvmem/scratchmemp
867c478bd9Sstevel@tonic-gate  *	|	| } MAPPEDMEM_RESERVE
877c478bd9Sstevel@tonic-gate  *	|-------| scratchresvp
887c478bd9Sstevel@tonic-gate  *	|	| } one page
897c478bd9Sstevel@tonic-gate  *	|-------| memlistpage (at roundup(_end, pagesize))
907c478bd9Sstevel@tonic-gate  *	|-------| _end
917c478bd9Sstevel@tonic-gate  *	| boot  |
927c478bd9Sstevel@tonic-gate  *	:	:
937c478bd9Sstevel@tonic-gate  *
947c478bd9Sstevel@tonic-gate  */
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate #define	MAPPEDMEM_RESERVE	(512*1024)	/* reserved for NOFAIL allocs */
977c478bd9Sstevel@tonic-gate 
987c478bd9Sstevel@tonic-gate #define	MAPPEDMEM_MINTOP	(caddr_t)(6*1024*1024)
997c478bd9Sstevel@tonic-gate #define	MAPPEDMEM_FULLTOP	(caddr_t)(10*1024*1024)
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate static caddr_t top_bootmem = MAPPEDMEM_MINTOP;
1027c478bd9Sstevel@tonic-gate static caddr_t top_resvmem, scratchresvp;
1037c478bd9Sstevel@tonic-gate 
104986fd29aSsetje /*
105986fd29aSsetje  * with newboot, boot goes away when it launches the client,
106986fd29aSsetje  * so we can safely extend bootmem on sg, and give it back
107986fd29aSsetje  * before we die.
108986fd29aSsetje  */
109986fd29aSsetje int is_sg;
110986fd29aSsetje caddr_t sg_addr;
111986fd29aSsetje size_t sg_len;
112986fd29aSsetje 
1137c478bd9Sstevel@tonic-gate static int
impl_name(char * buf,size_t bufsz)1147c478bd9Sstevel@tonic-gate impl_name(char *buf, size_t bufsz)
1157c478bd9Sstevel@tonic-gate {
116fa9e4066Sahrens 	pnode_t n = prom_rootnode();
1177c478bd9Sstevel@tonic-gate 	size_t len = prom_getproplen(n, "name");
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate 	if (len == 0 || len >= bufsz)
1207c478bd9Sstevel@tonic-gate 		return (-1);
1217c478bd9Sstevel@tonic-gate 
1227c478bd9Sstevel@tonic-gate 	(void) prom_getprop(n, "name", buf);
1237c478bd9Sstevel@tonic-gate 	buf[len] = '\0';
1247c478bd9Sstevel@tonic-gate 
1257c478bd9Sstevel@tonic-gate 	return (0);
1267c478bd9Sstevel@tonic-gate }
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate static caddr_t
vpage_from_freelist(size_t bytes)1297c478bd9Sstevel@tonic-gate vpage_from_freelist(size_t bytes)
1307c478bd9Sstevel@tonic-gate {
1317c478bd9Sstevel@tonic-gate 	caddr_t v;
1327c478bd9Sstevel@tonic-gate 	int i;
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate 	/* find first region which fits */
1357c478bd9Sstevel@tonic-gate 	for (i = 0; i < N_FREELIST && free_size[i] < bytes; i++)
1367c478bd9Sstevel@tonic-gate 		continue;
1377c478bd9Sstevel@tonic-gate 
1387c478bd9Sstevel@tonic-gate 	if (i == N_FREELIST) {
1397c478bd9Sstevel@tonic-gate 		dprintf("boot: failed to allocate %lu bytes from scratch "
1407c478bd9Sstevel@tonic-gate 		    "memory\n", bytes);
1417c478bd9Sstevel@tonic-gate 		return (NULL);
1427c478bd9Sstevel@tonic-gate 	}
1437c478bd9Sstevel@tonic-gate 
1447c478bd9Sstevel@tonic-gate 	v = free_addr[i];
1457c478bd9Sstevel@tonic-gate 	free_addr[i] += bytes;
1467c478bd9Sstevel@tonic-gate 	free_size[i] -= bytes;
1477c478bd9Sstevel@tonic-gate 	dprintf("reuse freed temp scratch:  bytes = %lu at %p\n", bytes,
1487c478bd9Sstevel@tonic-gate 	    (void *)v);
1497c478bd9Sstevel@tonic-gate 	return (v);
1507c478bd9Sstevel@tonic-gate }
1517c478bd9Sstevel@tonic-gate 
1527c478bd9Sstevel@tonic-gate /*
1537c478bd9Sstevel@tonic-gate  *	This routine will find the next PAGESIZE chunk in the
1547c478bd9Sstevel@tonic-gate  *	low MAPPEDMEM_MINTOP.  It is analogous to valloc(). It is only for boot
1557c478bd9Sstevel@tonic-gate  *	scratch memory, because child scratch memory goes up in
1567c478bd9Sstevel@tonic-gate  *	the the high memory.  We just need to verify that the
1577c478bd9Sstevel@tonic-gate  *	pages are on the list.  The calling routine will actually
1587c478bd9Sstevel@tonic-gate  *	remove them.
1597c478bd9Sstevel@tonic-gate  */
1607c478bd9Sstevel@tonic-gate static caddr_t
get_low_vpage(size_t numpages,enum RESOURCES type)1617c478bd9Sstevel@tonic-gate get_low_vpage(size_t numpages, enum RESOURCES type)
1627c478bd9Sstevel@tonic-gate {
1637c478bd9Sstevel@tonic-gate 	size_t bytes;
1647c478bd9Sstevel@tonic-gate 	caddr_t v;
1657c478bd9Sstevel@tonic-gate 
1667c478bd9Sstevel@tonic-gate 	if (!numpages)
1677c478bd9Sstevel@tonic-gate 		return (0);
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate 	/* We know the page is mapped because the 1st MAPPEDMEM_MINTOP is 1:1 */
1707c478bd9Sstevel@tonic-gate 	bytes = numpages * pagesize;
1717c478bd9Sstevel@tonic-gate 	if (scratchmemp + bytes <= top_bootmem) {
1727c478bd9Sstevel@tonic-gate 		v = scratchmemp;
1737c478bd9Sstevel@tonic-gate 		scratchmemp += bytes;
1747c478bd9Sstevel@tonic-gate 		return (v);
1757c478bd9Sstevel@tonic-gate 	}
1767c478bd9Sstevel@tonic-gate 
1777c478bd9Sstevel@tonic-gate 	/*
1787c478bd9Sstevel@tonic-gate 	 * If we run out of scratch memory, look in the freelist
1797c478bd9Sstevel@tonic-gate 	 */
1807c478bd9Sstevel@tonic-gate 	if ((v = vpage_from_freelist(bytes)) != NULL)
1817c478bd9Sstevel@tonic-gate 		return (v);
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate 	/*
1847c478bd9Sstevel@tonic-gate 	 * Try really hard for allocations that can't fail.  Look in the area
1857c478bd9Sstevel@tonic-gate 	 * that we've reserved for them.
1867c478bd9Sstevel@tonic-gate 	 */
1877c478bd9Sstevel@tonic-gate 	if (type == RES_BOOTSCRATCH_NOFAIL) {
1887c478bd9Sstevel@tonic-gate 		if (scratchresvp + bytes <= top_resvmem) {
1897c478bd9Sstevel@tonic-gate 			v = scratchresvp;
1907c478bd9Sstevel@tonic-gate 			scratchresvp += bytes;
1917c478bd9Sstevel@tonic-gate 			dprintf("using %lu bytes of reserved mem (%lu left)\n",
1927c478bd9Sstevel@tonic-gate 			    bytes, top_resvmem - scratchresvp);
1937c478bd9Sstevel@tonic-gate 			return (v);
1947c478bd9Sstevel@tonic-gate 		} else {
1957c478bd9Sstevel@tonic-gate 			printf("boot: failed to allocate %lu bytes from "
1967c478bd9Sstevel@tonic-gate 			    "reserved scratch memory\n", bytes);
1977c478bd9Sstevel@tonic-gate 			prom_panic("boot: scratch memory overflow.\n");
1987c478bd9Sstevel@tonic-gate 		}
1997c478bd9Sstevel@tonic-gate 	}
2007c478bd9Sstevel@tonic-gate 
2017c478bd9Sstevel@tonic-gate 	return (NULL);
2027c478bd9Sstevel@tonic-gate }
2037c478bd9Sstevel@tonic-gate 
2047c478bd9Sstevel@tonic-gate void
resalloc_init(void)2057c478bd9Sstevel@tonic-gate resalloc_init(void)
2067c478bd9Sstevel@tonic-gate {
2077c478bd9Sstevel@tonic-gate 	char iarch[128];
2087c478bd9Sstevel@tonic-gate 
2097c478bd9Sstevel@tonic-gate 	if (impl_name(iarch, sizeof (iarch)) < 0) {
2107c478bd9Sstevel@tonic-gate 		dprintf("boot: resalloc_init: failed to read iarch\n");
2117c478bd9Sstevel@tonic-gate 		return;
2127c478bd9Sstevel@tonic-gate 	}
2137c478bd9Sstevel@tonic-gate 
2147c478bd9Sstevel@tonic-gate 	dprintf("boot: resalloc_init: got iarch %s\n", iarch);
2157c478bd9Sstevel@tonic-gate 
2167c478bd9Sstevel@tonic-gate 	/*
2177c478bd9Sstevel@tonic-gate 	 * Some versions of SG/LW8 firmware can actually handle the entire 10MB,
2187c478bd9Sstevel@tonic-gate 	 * but we don't have the ability to check for the firmware version here.
2197c478bd9Sstevel@tonic-gate 	 */
2207c478bd9Sstevel@tonic-gate 	if (strcmp(iarch, "SUNW,Sun-Fire") == 0 ||
221986fd29aSsetje 	    strcmp(iarch, "SUNW,Netra-T12") == 0) {
222986fd29aSsetje 		is_sg = 1;
223986fd29aSsetje 		sg_addr = MAPPEDMEM_MINTOP;
224986fd29aSsetje 		sg_len = MAPPEDMEM_FULLTOP - MAPPEDMEM_MINTOP;
225986fd29aSsetje 		if (prom_alloc(sg_addr, sg_len, 1) != sg_addr)
226986fd29aSsetje 			prom_panic("can't extend sg bootmem");
227986fd29aSsetje 	}
2287c478bd9Sstevel@tonic-gate 
2297c478bd9Sstevel@tonic-gate 	top_bootmem = MAPPEDMEM_FULLTOP;
2307c478bd9Sstevel@tonic-gate 
2317c478bd9Sstevel@tonic-gate 	dprintf("boot: resalloc_init: boosted top_bootmem to %p\n",
2327c478bd9Sstevel@tonic-gate 	    (void *)top_bootmem);
2337c478bd9Sstevel@tonic-gate }
2347c478bd9Sstevel@tonic-gate 
2357c478bd9Sstevel@tonic-gate caddr_t
resalloc(enum RESOURCES type,size_t bytes,caddr_t virthint,int align)2367c478bd9Sstevel@tonic-gate resalloc(enum RESOURCES type, size_t bytes, caddr_t virthint, int align)
2377c478bd9Sstevel@tonic-gate {
2387c478bd9Sstevel@tonic-gate 	caddr_t	vaddr;
2397c478bd9Sstevel@tonic-gate 	long pmap = 0;
2407c478bd9Sstevel@tonic-gate 
2417c478bd9Sstevel@tonic-gate 	if (memlistpage == (caddr_t)0)
2427c478bd9Sstevel@tonic-gate 		reset_alloc();
2437c478bd9Sstevel@tonic-gate 
2447c478bd9Sstevel@tonic-gate 	if (bytes == 0)
2457c478bd9Sstevel@tonic-gate 		return ((caddr_t)0);
2467c478bd9Sstevel@tonic-gate 
2477c478bd9Sstevel@tonic-gate 	/* extend request to fill a page */
2487c478bd9Sstevel@tonic-gate 	bytes = roundup(bytes, pagesize);
2497c478bd9Sstevel@tonic-gate 
2507c478bd9Sstevel@tonic-gate 	dprintf("resalloc:  bytes = %lu\n", bytes);
2517c478bd9Sstevel@tonic-gate 
2527c478bd9Sstevel@tonic-gate 	switch (type) {
2537c478bd9Sstevel@tonic-gate 
2547c478bd9Sstevel@tonic-gate 	/*
2557c478bd9Sstevel@tonic-gate 	 * even V2 PROMs never bother to indicate whether the
2567c478bd9Sstevel@tonic-gate 	 * first MAPPEDMEM_MINTOP is taken or not.  So we do it all here.
2577c478bd9Sstevel@tonic-gate 	 * Smart PROM or no smart PROM.
2587c478bd9Sstevel@tonic-gate 	 */
2597c478bd9Sstevel@tonic-gate 	case RES_BOOTSCRATCH:
2607c478bd9Sstevel@tonic-gate 	case RES_BOOTSCRATCH_NOFAIL:
2617c478bd9Sstevel@tonic-gate 		vaddr = get_low_vpage((bytes/pagesize), type);
2627c478bd9Sstevel@tonic-gate 
2637c478bd9Sstevel@tonic-gate 		if (resalloc_debug) {
2647c478bd9Sstevel@tonic-gate 			dprintf("vaddr = %p, paddr = %lx\n", (void *)vaddr,
2657c478bd9Sstevel@tonic-gate 			    ptob(pmap));
2667c478bd9Sstevel@tonic-gate 			print_memlist(vfreelistp);
2677c478bd9Sstevel@tonic-gate 			print_memlist(pfreelistp);
2687c478bd9Sstevel@tonic-gate 		}
2697c478bd9Sstevel@tonic-gate 		return (vaddr);
2707c478bd9Sstevel@tonic-gate 		/*NOTREACHED*/
2717c478bd9Sstevel@tonic-gate 
2727c478bd9Sstevel@tonic-gate 	case RES_CHILDVIRT:
2737c478bd9Sstevel@tonic-gate 		vaddr = (caddr_t)prom_alloc(virthint, bytes, align);
2747c478bd9Sstevel@tonic-gate 
2757c478bd9Sstevel@tonic-gate 		if (vaddr == (caddr_t)virthint)
2767c478bd9Sstevel@tonic-gate 			return (vaddr);
2777c478bd9Sstevel@tonic-gate 		printf("Alloc of 0x%lx bytes at 0x%p refused.\n",
2787c478bd9Sstevel@tonic-gate 		    bytes, (void *)virthint);
2797c478bd9Sstevel@tonic-gate 		return ((caddr_t)0);
2807c478bd9Sstevel@tonic-gate 		/*NOTREACHED*/
2817c478bd9Sstevel@tonic-gate 
2827c478bd9Sstevel@tonic-gate 	default:
2837c478bd9Sstevel@tonic-gate 		printf("Bad resurce type\n");
2847c478bd9Sstevel@tonic-gate 		return ((caddr_t)0);
2857c478bd9Sstevel@tonic-gate 	}
2867c478bd9Sstevel@tonic-gate }
2877c478bd9Sstevel@tonic-gate 
2887c478bd9Sstevel@tonic-gate #ifdef	lint
2897c478bd9Sstevel@tonic-gate static char _end[1];	/* defined by the linker! */
2907c478bd9Sstevel@tonic-gate #endif	/* lint */
2917c478bd9Sstevel@tonic-gate 
2927c478bd9Sstevel@tonic-gate void
reset_alloc(void)2937c478bd9Sstevel@tonic-gate reset_alloc(void)
2947c478bd9Sstevel@tonic-gate {
2957c478bd9Sstevel@tonic-gate 	extern char _end[];
2967c478bd9Sstevel@tonic-gate 
2977c478bd9Sstevel@tonic-gate 	/* Cannot be called multiple times */
2987c478bd9Sstevel@tonic-gate 	if (memlistpage != (caddr_t)0)
2997c478bd9Sstevel@tonic-gate 		return;
3007c478bd9Sstevel@tonic-gate 
3017c478bd9Sstevel@tonic-gate 	/*
3027c478bd9Sstevel@tonic-gate 	 *  Due to kernel history and ease of programming, we
3037c478bd9Sstevel@tonic-gate 	 *  want to keep everything private to /boot BELOW MAPPEDMEM_MINTOP.
3047c478bd9Sstevel@tonic-gate 	 *  In this way, the kernel can just snarf it all when
3057c478bd9Sstevel@tonic-gate 	 *  when it is ready, and not worry about snarfing lists.
3067c478bd9Sstevel@tonic-gate 	 */
3077c478bd9Sstevel@tonic-gate 	memlistpage = (caddr_t)roundup((uintptr_t)_end, pagesize);
3087c478bd9Sstevel@tonic-gate 
3097c478bd9Sstevel@tonic-gate 	/*
3107c478bd9Sstevel@tonic-gate 	 *  This next is for scratch memory only
3117c478bd9Sstevel@tonic-gate 	 *  We only need 1 page in memlistpage for now
3127c478bd9Sstevel@tonic-gate 	 */
3137c478bd9Sstevel@tonic-gate 	scratchresvp = (caddr_t)(memlistpage + pagesize);
3147c478bd9Sstevel@tonic-gate 	scratchmemp = top_resvmem = scratchresvp + MAPPEDMEM_RESERVE;
3157c478bd9Sstevel@tonic-gate 	le_page = (caddr_t)(scratchmemp + pagesize);
3167c478bd9Sstevel@tonic-gate 	ie_page = (caddr_t)(le_page + pagesize);
3177c478bd9Sstevel@tonic-gate 
3187c478bd9Sstevel@tonic-gate 	bzero(memlistpage, pagesize);
3197c478bd9Sstevel@tonic-gate 	bzero(scratchmemp, pagesize);
3207c478bd9Sstevel@tonic-gate 	dprintf("memlistpage = %p\n", (void *)memlistpage);
3217c478bd9Sstevel@tonic-gate 	dprintf("le_page = %p\n", (void *)le_page);
3227c478bd9Sstevel@tonic-gate }
3237c478bd9Sstevel@tonic-gate 
3247c478bd9Sstevel@tonic-gate void
resfree(enum RESOURCES type,caddr_t virtaddr,size_t size)3257c478bd9Sstevel@tonic-gate resfree(enum RESOURCES type, caddr_t virtaddr, size_t size)
3267c478bd9Sstevel@tonic-gate {
3277c478bd9Sstevel@tonic-gate 	int i;
3287c478bd9Sstevel@tonic-gate 
3297c478bd9Sstevel@tonic-gate 	/* make sure this is boot scratch memory */
3307c478bd9Sstevel@tonic-gate 	switch (type) {
3317c478bd9Sstevel@tonic-gate 	case RES_BOOTSCRATCH:
3327c478bd9Sstevel@tonic-gate 		if (virtaddr + size > top_bootmem)
3337c478bd9Sstevel@tonic-gate 			return;
3347c478bd9Sstevel@tonic-gate 		break;
3357c478bd9Sstevel@tonic-gate 	default:
3367c478bd9Sstevel@tonic-gate 		return;
3377c478bd9Sstevel@tonic-gate 	}
3387c478bd9Sstevel@tonic-gate 
3397c478bd9Sstevel@tonic-gate 	/*
3407c478bd9Sstevel@tonic-gate 	 * Add this to the end of the free list
3417c478bd9Sstevel@tonic-gate 	 * NOTE: This relies on the fact that KRTLD calls BOP_FREE
3427c478bd9Sstevel@tonic-gate 	 *	from largest to smallest chunks.
3437c478bd9Sstevel@tonic-gate 	 */
3447c478bd9Sstevel@tonic-gate 	for (i = 0; i < N_FREELIST && free_size[i]; i++)
3457c478bd9Sstevel@tonic-gate 		;
3467c478bd9Sstevel@tonic-gate 	if (i == N_FREELIST)
3477c478bd9Sstevel@tonic-gate 		return;
3487c478bd9Sstevel@tonic-gate 	free_size[i] = size;
3497c478bd9Sstevel@tonic-gate 	free_addr[i] = virtaddr;
3507c478bd9Sstevel@tonic-gate }
351