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 2005 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 #include <sys/param.h> 30 #include <sys/sunddi.h> 31 #include <sys/bootconf.h> 32 #include <sys/bootvfs.h> 33 #include <sys/filep.h> 34 #include <sys/kobj.h> 35 #include <sys/varargs.h> 36 #include <sys/reboot.h> 37 38 extern void (*_kobj_printf)(void *, const char *fmt, ...); 39 extern int get_weakish_int(int *); 40 extern struct bootops *ops; 41 extern struct boot_fs_ops bufs_ops, bhsfs_ops; 42 extern int kmem_ready; 43 44 static uint64_t rd_start, rd_end; 45 struct boot_fs_ops *bfs_ops; 46 struct boot_fs_ops *bfs_tab[] = {&bufs_ops, &bhsfs_ops, NULL}; 47 48 #ifdef DEBUG 49 static uint64_t scratch_max; 50 #endif 51 52 #define _kmem_ready get_weakish_int(&kmem_ready) 53 54 /* 55 * This one reads the ramdisk. If fi_memp is set, we copy the 56 * ramdisk content to the designated buffer. Otherwise, we 57 * do a "cached" read (set fi_memp to the actual ramdisk buffer). 58 */ 59 int 60 diskread(fileid_t *filep) 61 { 62 uint_t blocknum; 63 caddr_t diskloc; 64 65 /* add in offset of root slice */ 66 blocknum = filep->fi_blocknum; 67 68 diskloc = (caddr_t)rd_start + blocknum * DEV_BSIZE; 69 if (diskloc + filep->fi_count > (caddr_t)rd_end) { 70 _kobj_printf(ops, "diskread: start = 0x%p, size = 0x%x\n", 71 diskloc, filep->fi_count); 72 _kobj_printf(ops, "reading beyond end of ramdisk\n"); 73 return (-1); 74 } 75 76 if (filep->fi_memp) { 77 bcopy(diskloc, filep->fi_memp, filep->fi_count); 78 } else { 79 /* "cached" read */ 80 filep->fi_memp = diskloc; 81 } 82 83 return (0); 84 } 85 86 int 87 kobj_boot_mountroot() 88 { 89 int i; 90 91 if (BOP_GETPROPLEN(ops, "ramdisk_start") != 8 || 92 BOP_GETPROP(ops, "ramdisk_start", (void *)&rd_start) != 0 || 93 BOP_GETPROPLEN(ops, "ramdisk_end") != 8 || 94 BOP_GETPROP(ops, "ramdisk_end", (void *)&rd_end) != 0) { 95 _kobj_printf(ops, 96 "failed to get ramdisk from boot\n"); 97 return (-1); 98 } 99 #ifdef KOBJ_DEBUG 100 _kobj_printf(ops, 101 "ramdisk range: 0x%llx-%llx\n", rd_start, rd_end); 102 #endif 103 104 for (i = 0; bfs_tab[i] != NULL; i++) { 105 bfs_ops = bfs_tab[i]; 106 if (BRD_MOUNTROOT(bfs_ops, "dummy") == 0) 107 return (0); 108 } 109 _kobj_printf(ops, "failed to mount ramdisk from boot\n"); 110 return (-1); 111 } 112 113 void 114 kobj_boot_unmountroot() 115 { 116 #ifdef DEBUG 117 if (boothowto & RB_VERBOSE) 118 _kobj_printf(ops, "boot scratch memory used: 0x%llx\n", 119 scratch_max); 120 #endif 121 (void) BRD_UNMOUNTROOT(bfs_ops); 122 } 123 124 void * 125 bkmem_alloc(size_t size) 126 { 127 /* allocate from boot scratch memory */ 128 void *addr; 129 130 if (_kmem_ready) 131 return (kobj_alloc(size, 0)); 132 133 addr = BOP_ALLOC(ops, 0, size, 0); 134 #ifdef DEBUG 135 if (scratch_max < (uint64_t)addr + size) 136 scratch_max = (uint64_t)addr + size; 137 #endif 138 return (addr); 139 } 140 141 /*ARGSUSED*/ 142 void 143 bkmem_free(void *p, size_t size) 144 { 145 /* 146 * Don't bother freeing scratch memory 147 * Note that in amd64, BOP_ALLOC returns address 148 * prepended with 0xffffffff, so we cast to 32-bit 149 * before comparing. 150 */ 151 if ((uint32_t)(uintptr_t)p > MAGIC_PHYS) 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