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