xref: /illumos-gate/usr/src/stand/lib/sa/memlist.c (revision 89b2a9fbeabf42fa54594df0e5927bcc50a07cc9)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 1992-2003 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <sys/types.h>
30 #include <sys/param.h>
31 #include <sys/sysmacros.h>
32 #include <sys/machparam.h>
33 #include <sys/promif.h>
34 #include <sys/bootconf.h>
35 #include <sys/salib.h>
36 
37 extern caddr_t memlistpage;
38 
39 /* Always pts to the next free link in the headtable */
40 /* i.e. it is always memlistpage+tableoffset */
41 caddr_t tablep = NULL;
42 static int table_freespace;
43 
44 /*
45  *	Function prototypes
46  */
47 extern void 		reset_alloc(void);
48 
49 void
50 print_memlist(struct memlist *av)
51 {
52 	struct memlist *p = av;
53 
54 	while (p != NULL) {
55 		printf("addr = 0x%x:0x%x, size = 0x%x:0x%x\n",
56 		    (uint_t)(p->address >> 32), (uint_t)p->address,
57 		    (uint_t)(p->size >> 32), (uint_t)p->size);
58 		p = p->next;
59 	}
60 
61 }
62 
63 /* allocate room for n bytes, return 8-byte aligned address */
64 void *
65 getlink(uint_t n)
66 {
67 	void *p;
68 	extern int pagesize;
69 
70 	if (memlistpage == NULL)
71 		reset_alloc();
72 
73 	if (tablep == NULL) {
74 		/*
75 		 * Took the following 2 lines out of above test for
76 		 * memlistpage == null so we can initialize table_freespace
77 		 */
78 		table_freespace = pagesize - sizeof (struct bsys_mem);
79 		tablep = memlistpage + sizeof (struct bsys_mem);
80 		tablep = (caddr_t)roundup((uintptr_t)tablep, 8);
81 	}
82 
83 	if (n == 0)
84 		return (NULL);
85 
86 	n = roundup(n, 8);
87 	p = tablep;
88 
89 	table_freespace -= n;
90 	tablep += n;
91 	if (table_freespace <= 0) {
92 		char buf[80];
93 
94 		(void) sprintf(buf,
95 		    "Boot getlink(): no memlist space (need %d)\n", n);
96 		prom_panic(buf);
97 	}
98 
99 	return (p);
100 }
101 
102 
103 /*
104  * This is the number of memlist structures allocated in one shot. kept
105  * to small number to reduce wastage of memory, it should not be too small
106  * to slow down boot.
107  */
108 #define		ALLOC_SZ	5
109 static struct memlist *free_memlist_ptr = NULL;
110 
111 /*
112  * Free memory lists are maintained as simple single linked lists.
113  * get_memlist_struct returns a memlist structure without initializing
114  * any of the fields.  It is caller's responsibility to do that.
115  */
116 
117 struct memlist *
118 get_memlist_struct(void)
119 {
120 	struct memlist *ptr;
121 	int i;
122 
123 	if (free_memlist_ptr == NULL) {
124 		ptr = free_memlist_ptr = getlink(ALLOC_SZ *
125 		    sizeof (struct memlist));
126 		bzero(free_memlist_ptr, (ALLOC_SZ * sizeof (struct memlist)));
127 		for (i = 0; i < ALLOC_SZ; i++)
128 			ptr[i].next = &ptr[i+1];
129 		ptr[i-1].next = NULL;
130 	}
131 	ptr = free_memlist_ptr;
132 	free_memlist_ptr = ptr->next;
133 	return (ptr);
134 }
135 
136 /*
137  * Return memlist structure to free list.
138  */
139 void
140 add_to_freelist(struct memlist *ptr)
141 {
142 	struct memlist *tmp;
143 
144 	if (free_memlist_ptr == NULL) {
145 		free_memlist_ptr = ptr;
146 	} else {
147 		for (tmp = free_memlist_ptr; tmp->next; tmp = tmp->next)
148 			;
149 		tmp->next = ptr;
150 	}
151 }
152