1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 1996-2003 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate /* 30*0Sstevel@tonic-gate * Implementation of the vestigial bootops vector for platforms using the 31*0Sstevel@tonic-gate * 1275-like boot interfaces. 32*0Sstevel@tonic-gate */ 33*0Sstevel@tonic-gate 34*0Sstevel@tonic-gate #include <sys/types.h> 35*0Sstevel@tonic-gate #include <sys/bootconf.h> 36*0Sstevel@tonic-gate #include <sys/param.h> 37*0Sstevel@tonic-gate #include <sys/obpdefs.h> 38*0Sstevel@tonic-gate #include <sys/promif.h> 39*0Sstevel@tonic-gate #include <sys/salib.h> 40*0Sstevel@tonic-gate #include <sys/boot.h> 41*0Sstevel@tonic-gate #include <stddef.h> 42*0Sstevel@tonic-gate #include "boot_plat.h" 43*0Sstevel@tonic-gate 44*0Sstevel@tonic-gate #ifdef DEBUG 45*0Sstevel@tonic-gate extern int debug; 46*0Sstevel@tonic-gate #else 47*0Sstevel@tonic-gate static const int debug = 0; 48*0Sstevel@tonic-gate #endif 49*0Sstevel@tonic-gate 50*0Sstevel@tonic-gate #define dprintf if (debug) printf 51*0Sstevel@tonic-gate 52*0Sstevel@tonic-gate extern void closeall(int); 53*0Sstevel@tonic-gate 54*0Sstevel@tonic-gate /* 55*0Sstevel@tonic-gate * This is the number for this version of bootops, which is vestigial. 56*0Sstevel@tonic-gate * Standalones that require the old bootops will look in bootops.bsys_version, 57*0Sstevel@tonic-gate * see this number is higher than they expect and fail gracefully. 58*0Sstevel@tonic-gate * They can make this "peek" successfully even if they are ILP32 programs. 59*0Sstevel@tonic-gate */ 60*0Sstevel@tonic-gate int boot_version = BO_VERSION; 61*0Sstevel@tonic-gate 62*0Sstevel@tonic-gate struct bootops bootops; 63*0Sstevel@tonic-gate 64*0Sstevel@tonic-gate void 65*0Sstevel@tonic-gate setup_bootops(void) 66*0Sstevel@tonic-gate { 67*0Sstevel@tonic-gate /* sanity-check bsys_printf - old kernels need to fail with a message */ 68*0Sstevel@tonic-gate #if !defined(lint) 69*0Sstevel@tonic-gate if (offsetof(struct bootops, bsys_printf) != 60) { 70*0Sstevel@tonic-gate printf("boot: bsys_printf is at offset 0x%lx instead of 60\n" 71*0Sstevel@tonic-gate "boot: this will likely make old kernels die without " 72*0Sstevel@tonic-gate "printing a message.\n", 73*0Sstevel@tonic-gate offsetof(struct bootops, bsys_printf)); 74*0Sstevel@tonic-gate } 75*0Sstevel@tonic-gate /* sanity-check bsys_1275_call - if it moves, kernels cannot boot */ 76*0Sstevel@tonic-gate if (offsetof(struct bootops, bsys_1275_call) != 24) { 77*0Sstevel@tonic-gate printf("boot: bsys_1275_call is at offset 0x%lx instead of 24\n" 78*0Sstevel@tonic-gate "boot: this will likely break the kernel\n", 79*0Sstevel@tonic-gate offsetof(struct bootops, bsys_1275_call)); 80*0Sstevel@tonic-gate } 81*0Sstevel@tonic-gate #endif 82*0Sstevel@tonic-gate bootops.bsys_version = boot_version; 83*0Sstevel@tonic-gate bootops.bsys_1275_call = (uint64_t)boot1275_entry; 84*0Sstevel@tonic-gate /* so old kernels die with a message */ 85*0Sstevel@tonic-gate bootops.bsys_printf = (uint32_t)boot_fail_gracefully; 86*0Sstevel@tonic-gate 87*0Sstevel@tonic-gate if (!memlistpage) /* paranoia runs rampant */ 88*0Sstevel@tonic-gate prom_panic("\nMemlistpage not setup yet."); 89*0Sstevel@tonic-gate /* 90*0Sstevel@tonic-gate * The memory list should always be updated last. The prom 91*0Sstevel@tonic-gate * calls which are made to update a memory list may have the 92*0Sstevel@tonic-gate * undesirable affect of claiming physical memory. This may 93*0Sstevel@tonic-gate * happen after the kernel has created its page free list. 94*0Sstevel@tonic-gate * The kernel deals with this by comparing the n and n-1 95*0Sstevel@tonic-gate * snapshots of memory. Updating the memory available list 96*0Sstevel@tonic-gate * last guarantees we will have a current, accurate snapshot. 97*0Sstevel@tonic-gate * See bug #1260786. 98*0Sstevel@tonic-gate */ 99*0Sstevel@tonic-gate update_memlist("virtual-memory", "available", &vfreelistp); 100*0Sstevel@tonic-gate update_memlist("memory", "available", &pfreelistp); 101*0Sstevel@tonic-gate 102*0Sstevel@tonic-gate dprintf("\nPhysinstalled: "); 103*0Sstevel@tonic-gate if (debug) print_memlist(pinstalledp); 104*0Sstevel@tonic-gate dprintf("\nPhysfree: "); 105*0Sstevel@tonic-gate if (debug) print_memlist(pfreelistp); 106*0Sstevel@tonic-gate dprintf("\nVirtfree: "); 107*0Sstevel@tonic-gate if (debug) print_memlist(vfreelistp); 108*0Sstevel@tonic-gate } 109*0Sstevel@tonic-gate 110*0Sstevel@tonic-gate void 111*0Sstevel@tonic-gate install_memlistptrs(void) 112*0Sstevel@tonic-gate { 113*0Sstevel@tonic-gate 114*0Sstevel@tonic-gate /* prob only need 1 page for now */ 115*0Sstevel@tonic-gate memlistextent = tablep - memlistpage; 116*0Sstevel@tonic-gate 117*0Sstevel@tonic-gate dprintf("physinstalled = %p\n", (void *)pinstalledp); 118*0Sstevel@tonic-gate dprintf("physavail = %p\n", (void *)pfreelistp); 119*0Sstevel@tonic-gate dprintf("virtavail = %p\n", (void *)vfreelistp); 120*0Sstevel@tonic-gate dprintf("extent = 0x%lx\n", memlistextent); 121*0Sstevel@tonic-gate } 122*0Sstevel@tonic-gate 123*0Sstevel@tonic-gate /* 124*0Sstevel@tonic-gate * A word of explanation is in order. 125*0Sstevel@tonic-gate * This routine is meant to be called during 126*0Sstevel@tonic-gate * boot_release(), when the kernel is trying 127*0Sstevel@tonic-gate * to ascertain the current state of memory 128*0Sstevel@tonic-gate * so that it can use a memlist to walk itself 129*0Sstevel@tonic-gate * thru kvm_init(). 130*0Sstevel@tonic-gate */ 131*0Sstevel@tonic-gate 132*0Sstevel@tonic-gate void 133*0Sstevel@tonic-gate update_memlist(char *name, char *prop, struct memlist **list) 134*0Sstevel@tonic-gate { 135*0Sstevel@tonic-gate /* Just take another prom snapshot */ 136*0Sstevel@tonic-gate *list = fill_memlists(name, prop, *list); 137*0Sstevel@tonic-gate install_memlistptrs(); 138*0Sstevel@tonic-gate } 139*0Sstevel@tonic-gate 140*0Sstevel@tonic-gate /* 141*0Sstevel@tonic-gate * This routine is meant to be called by the 142*0Sstevel@tonic-gate * kernel to shut down all boot and prom activity. 143*0Sstevel@tonic-gate * After this routine is called, PROM or boot IO is no 144*0Sstevel@tonic-gate * longer possible, nor is memory allocation. 145*0Sstevel@tonic-gate */ 146*0Sstevel@tonic-gate void 147*0Sstevel@tonic-gate kern_killboot(void) 148*0Sstevel@tonic-gate { 149*0Sstevel@tonic-gate if (verbosemode) { 150*0Sstevel@tonic-gate dprintf("Entering boot_release()\n"); 151*0Sstevel@tonic-gate dprintf("\nPhysinstalled: "); 152*0Sstevel@tonic-gate if (debug) print_memlist(pinstalledp); 153*0Sstevel@tonic-gate dprintf("\nPhysfree: "); 154*0Sstevel@tonic-gate if (debug) print_memlist(pfreelistp); 155*0Sstevel@tonic-gate dprintf("\nVirtfree: "); 156*0Sstevel@tonic-gate if (debug) print_memlist(vfreelistp); 157*0Sstevel@tonic-gate } 158*0Sstevel@tonic-gate if (debug) { 159*0Sstevel@tonic-gate dprintf("Calling quiesce_io()\n"); 160*0Sstevel@tonic-gate prom_enter_mon(); 161*0Sstevel@tonic-gate } 162*0Sstevel@tonic-gate 163*0Sstevel@tonic-gate /* close all open devices */ 164*0Sstevel@tonic-gate closeall(1); 165*0Sstevel@tonic-gate 166*0Sstevel@tonic-gate /* 167*0Sstevel@tonic-gate * Now we take YAPS (yet another Prom snapshot) of 168*0Sstevel@tonic-gate * memory, just for safety sake. 169*0Sstevel@tonic-gate * 170*0Sstevel@tonic-gate * The memory list should always be updated last. The prom 171*0Sstevel@tonic-gate * calls which are made to update a memory list may have the 172*0Sstevel@tonic-gate * undesirable affect of claiming physical memory. This may 173*0Sstevel@tonic-gate * happen after the kernel has created its page free list. 174*0Sstevel@tonic-gate * The kernel deals with this by comparing the n and n-1 175*0Sstevel@tonic-gate * snapshots of memory. Updating the memory available list 176*0Sstevel@tonic-gate * last guarantees we will have a current, accurate snapshot. 177*0Sstevel@tonic-gate * See bug #1260786. 178*0Sstevel@tonic-gate */ 179*0Sstevel@tonic-gate update_memlist("virtual-memory", "available", &vfreelistp); 180*0Sstevel@tonic-gate update_memlist("memory", "available", &pfreelistp); 181*0Sstevel@tonic-gate 182*0Sstevel@tonic-gate if (verbosemode) { 183*0Sstevel@tonic-gate dprintf("physinstalled = %p\n", (void *)pinstalledp); 184*0Sstevel@tonic-gate dprintf("physavail = %p\n", (void *)pfreelistp); 185*0Sstevel@tonic-gate dprintf("virtavail = %p\n", (void *)vfreelistp); 186*0Sstevel@tonic-gate dprintf("extent = 0x%lx\n", memlistextent); 187*0Sstevel@tonic-gate dprintf("Leaving boot_release()\n"); 188*0Sstevel@tonic-gate 189*0Sstevel@tonic-gate dprintf("Physinstalled: \n"); 190*0Sstevel@tonic-gate if (debug) 191*0Sstevel@tonic-gate print_memlist(pinstalledp); 192*0Sstevel@tonic-gate 193*0Sstevel@tonic-gate dprintf("Physfree:\n"); 194*0Sstevel@tonic-gate if (debug) 195*0Sstevel@tonic-gate print_memlist(pfreelistp); 196*0Sstevel@tonic-gate 197*0Sstevel@tonic-gate dprintf("Virtfree: \n"); 198*0Sstevel@tonic-gate if (debug) 199*0Sstevel@tonic-gate print_memlist(vfreelistp); 200*0Sstevel@tonic-gate } 201*0Sstevel@tonic-gate 202*0Sstevel@tonic-gate #ifdef DEBUG_MMU 203*0Sstevel@tonic-gate dump_mmu(); 204*0Sstevel@tonic-gate prom_enter_mon(); 205*0Sstevel@tonic-gate #endif 206*0Sstevel@tonic-gate } 207*0Sstevel@tonic-gate 208*0Sstevel@tonic-gate void 209*0Sstevel@tonic-gate boot_fail_gracefully(void) 210*0Sstevel@tonic-gate { 211*0Sstevel@tonic-gate prom_panic( 212*0Sstevel@tonic-gate "mismatched version of /boot interface: new boot, old kernel"); 213*0Sstevel@tonic-gate } 214