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 2007 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <sys/types.h>
27 #include <sys/bootconf.h>
28 #include <sys/param.h>
29 #include <sys/obpdefs.h>
30 #include <sys/promif.h>
31 #include <sys/salib.h>
32 #include <sys/boot.h>
33 #include <stddef.h>
34 #include "boot_plat.h"
35 
36 #ifdef DEBUG
37 extern int debug;
38 #else
39 static const int debug = 0;
40 #endif
41 
42 #define	dprintf		if (debug) printf
43 
44 extern void	closeall(int);
45 
46 struct bootops bootops;
47 
48 static void
boot_fail(void)49 boot_fail(void)
50 {
51 	prom_panic("bootops is gone, it should not be called");
52 }
53 
54 void
setup_bootops(void)55 setup_bootops(void)
56 {
57 	bootops.bsys_version = BO_VERSION;
58 	bootops.bsys_1275_call = (uint64_t)boot_fail;
59 	bootops.bsys_printf = (uint32_t)(uintptr_t)boot_fail;
60 
61 	if (!memlistpage) /* paranoia runs rampant */
62 		prom_panic("\nMemlistpage not setup yet.");
63 	/*
64 	 * The memory list should always be updated last.  The prom
65 	 * calls which are made to update a memory list may have the
66 	 * undesirable affect of claiming physical memory.  This may
67 	 * happen after the kernel has created its page free list.
68 	 * The kernel deals with this by comparing the n and n-1
69 	 * snapshots of memory.  Updating the memory available list
70 	 * last guarantees we will have a current, accurate snapshot.
71 	 * See bug #1260786.
72 	 */
73 	update_memlist("virtual-memory", "available", &vfreelistp);
74 	update_memlist("memory", "available", &pfreelistp);
75 
76 	dprintf("\nPhysinstalled: ");
77 	if (debug) print_memlist(pinstalledp);
78 	dprintf("\nPhysfree: ");
79 	if (debug) print_memlist(pfreelistp);
80 	dprintf("\nVirtfree: ");
81 	if (debug) print_memlist(vfreelistp);
82 }
83 
84 void
install_memlistptrs(void)85 install_memlistptrs(void)
86 {
87 
88 	/* prob only need 1 page for now */
89 	memlistextent = tablep - memlistpage;
90 
91 	dprintf("physinstalled = %p\n", (void *)pinstalledp);
92 	dprintf("physavail = %p\n", (void *)pfreelistp);
93 	dprintf("virtavail = %p\n", (void *)vfreelistp);
94 	dprintf("extent = 0x%lx\n", memlistextent);
95 }
96 
97 /*
98  *      A word of explanation is in order.
99  *      This routine is meant to be called during
100  *      boot_release(), when the kernel is trying
101  *      to ascertain the current state of memory
102  *      so that it can use a memlist to walk itself
103  *      thru kvm_init().
104  */
105 
106 void
update_memlist(char * name,char * prop,struct memlist ** list)107 update_memlist(char *name, char *prop, struct memlist **list)
108 {
109 	/* Just take another prom snapshot */
110 	*list = fill_memlists(name, prop, *list);
111 	install_memlistptrs();
112 }
113 
114 /*
115  *  This routine is meant to be called by the
116  *  kernel to shut down all boot and prom activity.
117  *  After this routine is called, PROM or boot IO is no
118  *  longer possible, nor is memory allocation.
119  */
120 void
kern_killboot(void)121 kern_killboot(void)
122 {
123 	if (verbosemode) {
124 		dprintf("Entering boot_release()\n");
125 		dprintf("\nPhysinstalled: ");
126 		if (debug) print_memlist(pinstalledp);
127 		dprintf("\nPhysfree: ");
128 		if (debug) print_memlist(pfreelistp);
129 		dprintf("\nVirtfree: ");
130 		if (debug) print_memlist(vfreelistp);
131 	}
132 	if (debug) {
133 		dprintf("Calling quiesce_io()\n");
134 		prom_enter_mon();
135 	}
136 
137 	/* close all open devices */
138 	closeall(1);
139 
140 	/*
141 	 *  Now we take YAPS (yet another Prom snapshot) of
142 	 *  memory, just for safety sake.
143 	 *
144 	 * The memory list should always be updated last.  The prom
145 	 * calls which are made to update a memory list may have the
146 	 * undesirable affect of claiming physical memory.  This may
147 	 * happen after the kernel has created its page free list.
148 	 * The kernel deals with this by comparing the n and n-1
149 	 * snapshots of memory.  Updating the memory available list
150 	 * last guarantees we will have a current, accurate snapshot.
151 	 * See bug #1260786.
152 	 */
153 	update_memlist("virtual-memory", "available", &vfreelistp);
154 	update_memlist("memory", "available", &pfreelistp);
155 
156 	if (verbosemode) {
157 		dprintf("physinstalled = %p\n", (void *)pinstalledp);
158 		dprintf("physavail = %p\n", (void *)pfreelistp);
159 		dprintf("virtavail = %p\n", (void *)vfreelistp);
160 		dprintf("extent = 0x%lx\n", memlistextent);
161 		dprintf("Leaving boot_release()\n");
162 
163 		dprintf("Physinstalled: \n");
164 		if (debug)
165 			print_memlist(pinstalledp);
166 
167 		dprintf("Physfree:\n");
168 		if (debug)
169 			print_memlist(pfreelistp);
170 
171 		dprintf("Virtfree: \n");
172 		if (debug)
173 			print_memlist(vfreelistp);
174 	}
175 
176 #ifdef DEBUG_MMU
177 	dump_mmu();
178 	prom_enter_mon();
179 #endif
180 }
181