xref: /titanic_52/usr/src/psm/stand/boot/sparc/common/bootops.c (revision bdfc6d18da790deeec2e0eb09c625902defe2498)
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 1996-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 /*
30  * Implementation of the vestigial bootops vector for platforms using the
31  * 1275-like boot interfaces.
32  */
33 
34 #include <sys/types.h>
35 #include <sys/bootconf.h>
36 #include <sys/param.h>
37 #include <sys/obpdefs.h>
38 #include <sys/promif.h>
39 #include <sys/salib.h>
40 #include <sys/boot.h>
41 #include <stddef.h>
42 #include "boot_plat.h"
43 
44 #ifdef DEBUG
45 extern int debug;
46 #else
47 static const int debug = 0;
48 #endif
49 
50 #define	dprintf		if (debug) printf
51 
52 extern void	closeall(int);
53 
54 /*
55  * This is the number for this version of bootops, which is vestigial.
56  * Standalones that require the old bootops will look in bootops.bsys_version,
57  * see this number is higher than they expect and fail gracefully.
58  * They can make this "peek" successfully even if they are ILP32 programs.
59  */
60 int boot_version = BO_VERSION;
61 
62 struct bootops bootops;
63 
64 void
65 setup_bootops(void)
66 {
67 	/* sanity-check bsys_printf - old kernels need to fail with a message */
68 #if !defined(lint)
69 	if (offsetof(struct bootops, bsys_printf) != 60) {
70 		printf("boot: bsys_printf is at offset 0x%lx instead of 60\n"
71 		    "boot: this will likely make old kernels die without "
72 		    "printing a message.\n",
73 		    offsetof(struct bootops, bsys_printf));
74 	}
75 	/* sanity-check bsys_1275_call - if it moves, kernels cannot boot */
76 	if (offsetof(struct bootops, bsys_1275_call) != 24) {
77 		printf("boot: bsys_1275_call is at offset 0x%lx instead of 24\n"
78 			"boot: this will likely break the kernel\n",
79 		    offsetof(struct bootops, bsys_1275_call));
80 	}
81 #endif
82 	bootops.bsys_version = boot_version;
83 	bootops.bsys_1275_call = (uint64_t)boot1275_entry;
84 	/* so old kernels die with a message */
85 	bootops.bsys_printf = (uint32_t)boot_fail_gracefully;
86 
87 	if (!memlistpage) /* paranoia runs rampant */
88 		prom_panic("\nMemlistpage not setup yet.");
89 	/*
90 	 * The memory list should always be updated last.  The prom
91 	 * calls which are made to update a memory list may have the
92 	 * undesirable affect of claiming physical memory.  This may
93 	 * happen after the kernel has created its page free list.
94 	 * The kernel deals with this by comparing the n and n-1
95 	 * snapshots of memory.  Updating the memory available list
96 	 * last guarantees we will have a current, accurate snapshot.
97 	 * See bug #1260786.
98 	 */
99 	update_memlist("virtual-memory", "available", &vfreelistp);
100 	update_memlist("memory", "available", &pfreelistp);
101 
102 	dprintf("\nPhysinstalled: ");
103 	if (debug) print_memlist(pinstalledp);
104 	dprintf("\nPhysfree: ");
105 	if (debug) print_memlist(pfreelistp);
106 	dprintf("\nVirtfree: ");
107 	if (debug) print_memlist(vfreelistp);
108 }
109 
110 void
111 install_memlistptrs(void)
112 {
113 
114 	/* prob only need 1 page for now */
115 	memlistextent = tablep - memlistpage;
116 
117 	dprintf("physinstalled = %p\n", (void *)pinstalledp);
118 	dprintf("physavail = %p\n", (void *)pfreelistp);
119 	dprintf("virtavail = %p\n", (void *)vfreelistp);
120 	dprintf("extent = 0x%lx\n", memlistextent);
121 }
122 
123 /*
124  *      A word of explanation is in order.
125  *      This routine is meant to be called during
126  *      boot_release(), when the kernel is trying
127  *      to ascertain the current state of memory
128  *      so that it can use a memlist to walk itself
129  *      thru kvm_init().
130  */
131 
132 void
133 update_memlist(char *name, char *prop, struct memlist **list)
134 {
135 	/* Just take another prom snapshot */
136 	*list = fill_memlists(name, prop, *list);
137 	install_memlistptrs();
138 }
139 
140 /*
141  *  This routine is meant to be called by the
142  *  kernel to shut down all boot and prom activity.
143  *  After this routine is called, PROM or boot IO is no
144  *  longer possible, nor is memory allocation.
145  */
146 void
147 kern_killboot(void)
148 {
149 	if (verbosemode) {
150 		dprintf("Entering boot_release()\n");
151 		dprintf("\nPhysinstalled: ");
152 		if (debug) print_memlist(pinstalledp);
153 		dprintf("\nPhysfree: ");
154 		if (debug) print_memlist(pfreelistp);
155 		dprintf("\nVirtfree: ");
156 		if (debug) print_memlist(vfreelistp);
157 	}
158 	if (debug) {
159 		dprintf("Calling quiesce_io()\n");
160 		prom_enter_mon();
161 	}
162 
163 	/* close all open devices */
164 	closeall(1);
165 
166 	/*
167 	 *  Now we take YAPS (yet another Prom snapshot) of
168 	 *  memory, just for safety sake.
169 	 *
170 	 * The memory list should always be updated last.  The prom
171 	 * calls which are made to update a memory list may have the
172 	 * undesirable affect of claiming physical memory.  This may
173 	 * happen after the kernel has created its page free list.
174 	 * The kernel deals with this by comparing the n and n-1
175 	 * snapshots of memory.  Updating the memory available list
176 	 * last guarantees we will have a current, accurate snapshot.
177 	 * See bug #1260786.
178 	 */
179 	update_memlist("virtual-memory", "available", &vfreelistp);
180 	update_memlist("memory", "available", &pfreelistp);
181 
182 	if (verbosemode) {
183 		dprintf("physinstalled = %p\n", (void *)pinstalledp);
184 		dprintf("physavail = %p\n", (void *)pfreelistp);
185 		dprintf("virtavail = %p\n", (void *)vfreelistp);
186 		dprintf("extent = 0x%lx\n", memlistextent);
187 		dprintf("Leaving boot_release()\n");
188 
189 		dprintf("Physinstalled: \n");
190 		if (debug)
191 			print_memlist(pinstalledp);
192 
193 		dprintf("Physfree:\n");
194 		if (debug)
195 			print_memlist(pfreelistp);
196 
197 		dprintf("Virtfree: \n");
198 		if (debug)
199 			print_memlist(vfreelistp);
200 	}
201 
202 #ifdef DEBUG_MMU
203 	dump_mmu();
204 	prom_enter_mon();
205 #endif
206 }
207 
208 void
209 boot_fail_gracefully(void)
210 {
211 	prom_panic(
212 	    "mismatched version of /boot interface: new boot, old kernel");
213 }
214