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 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 27 #include <sys/param.h> 28 #include <sys/sunddi.h> 29 #include <sys/bootconf.h> 30 #include <sys/bootvfs.h> 31 #include <sys/filep.h> 32 #include <sys/kobj.h> 33 #include <sys/varargs.h> 34 #include <sys/reboot.h> 35 36 extern void (*_kobj_printf)(void *, const char *fmt, ...); 37 extern int get_weakish_int(int *); 38 extern struct bootops *ops; 39 extern struct boot_fs_ops bufs_ops, bhsfs_ops; 40 extern int kmem_ready; 41 42 static uint64_t rd_start, rd_end; 43 struct boot_fs_ops *bfs_ops; 44 struct boot_fs_ops *bfs_tab[] = {&bufs_ops, &bhsfs_ops, NULL}; 45 46 static uintptr_t scratch_max = 0; 47 48 #define _kmem_ready get_weakish_int(&kmem_ready) 49 50 /* 51 * This one reads the ramdisk. If fi_memp is set, we copy the 52 * ramdisk content to the designated buffer. Otherwise, we 53 * do a "cached" read (set fi_memp to the actual ramdisk buffer). 54 */ 55 int 56 diskread(fileid_t *filep) 57 { 58 uint_t blocknum; 59 caddr_t diskloc; 60 61 /* add in offset of root slice */ 62 blocknum = filep->fi_blocknum; 63 64 diskloc = (caddr_t)(uintptr_t)rd_start + blocknum * DEV_BSIZE; 65 if (diskloc + filep->fi_count > (caddr_t)(uintptr_t)rd_end) { 66 _kobj_printf(ops, "diskread: start = 0x%p, size = 0x%x\n", 67 diskloc, filep->fi_count); 68 _kobj_printf(ops, "reading beyond end of ramdisk\n"); 69 return (-1); 70 } 71 72 if (filep->fi_memp) { 73 bcopy(diskloc, filep->fi_memp, filep->fi_count); 74 } else { 75 /* "cached" read */ 76 filep->fi_memp = diskloc; 77 } 78 79 return (0); 80 } 81 82 int 83 kobj_boot_mountroot() 84 { 85 int i; 86 87 if (BOP_GETPROPLEN(ops, "ramdisk_start") != 8 || 88 BOP_GETPROP(ops, "ramdisk_start", (void *)&rd_start) != 0 || 89 BOP_GETPROPLEN(ops, "ramdisk_end") != 8 || 90 BOP_GETPROP(ops, "ramdisk_end", (void *)&rd_end) != 0) { 91 _kobj_printf(ops, 92 "failed to get ramdisk from boot\n"); 93 return (-1); 94 } 95 #ifdef KOBJ_DEBUG 96 _kobj_printf(ops, 97 "ramdisk range: 0x%llx-%llx\n", rd_start, rd_end); 98 #endif 99 100 for (i = 0; bfs_tab[i] != NULL; i++) { 101 bfs_ops = bfs_tab[i]; 102 if (BRD_MOUNTROOT(bfs_ops, "dummy") == 0) 103 return (0); 104 } 105 _kobj_printf(ops, "failed to mount ramdisk from boot\n"); 106 return (-1); 107 } 108 109 void 110 kobj_boot_unmountroot() 111 { 112 #ifdef DEBUG 113 if (boothowto & RB_VERBOSE) 114 _kobj_printf(ops, "boot scratch memory used: 0x%lx\n", 115 scratch_max); 116 #endif 117 (void) BRD_UNMOUNTROOT(bfs_ops); 118 } 119 120 /* 121 * Boot time wrappers for memory allocators. Called for both permanent 122 * and temporary boot memory allocations. We have to track which allocator 123 * (boot or kmem) was used so that we know how to free. 124 */ 125 void * 126 bkmem_alloc(size_t size) 127 { 128 /* allocate from boot scratch memory */ 129 void *addr; 130 131 if (_kmem_ready) 132 return (kobj_alloc(size, 0)); 133 134 /* 135 * Remember the highest BOP_ALLOC allocated address and don't free 136 * anything below it. 137 */ 138 addr = BOP_ALLOC(ops, 0, size, 0); 139 if (scratch_max < (uintptr_t)addr + size) 140 scratch_max = (uintptr_t)addr + size; 141 return (addr); 142 } 143 144 /*ARGSUSED*/ 145 void 146 bkmem_free(void *p, size_t size) 147 { 148 /* 149 * Free only if it's not boot scratch memory. 150 */ 151 if ((uintptr_t)p >= scratch_max) 152 kobj_free(p, size); 153 } 154 155 /*PRINTFLIKE1*/ 156 void 157 kobj_printf(char *fmt, ...) 158 { 159 va_list adx; 160 161 va_start(adx, fmt); 162 _kobj_printf(ops, fmt, adx); 163 va_end(adx); 164 } 165