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/machsystm.h> 30 #include <sys/vm.h> 31 #include <sys/cpu.h> 32 #include <sys/intreg.h> 33 #include <sys/machcpuvar.h> 34 #include <sys/machparam.h> 35 #include <vm/hat_sfmmu.h> 36 #include <vm/seg_kmem.h> 37 #include <sys/error.h> 38 #include <sys/hypervisor_api.h> 39 #include <sys/types.h> 40 #include <sys/kstat.h> 41 #ifdef MACH_DESC_DEBUG 42 #include <sys/promif.h> /* for prom_printf */ 43 #endif 44 #include <sys/sysmacros.h> 45 #include <sys/mach_descrip.h> 46 47 /* 48 * Basic code to pull in the machine description from the Hypervisor 49 * An equivalent to this should really be available from mlsetup 50 * for really early info, but for the time being we are content to 51 * invoke this from startup_end once the VM system has been initialised. 52 * To do this we use the intrq allocator which means that 53 * this function should be called after intrq_init(); 54 * We try and do this early enough however that it is useful to other 55 * components within the kernel. 56 * Also, user-level entities can grab the machine description via 57 * kstat and/or the mdesc device driver. 58 */ 59 60 61 machine_descrip_t machine_descrip; 62 63 64 #ifdef MACH_DESC_DEBUG 65 #define MDP(ARGS) prom_printf ARGS 66 static void 67 dump_buf(uint8_t *bufp, int size) 68 { 69 int i; 70 for (i = 0; i < size; i += 16) { 71 int j; 72 prom_printf("0x%04x :", i); 73 for (j = 0; j < 16 && (i+j) < size; j++) 74 prom_printf(" %02x", bufp[i+j]); 75 prom_printf("\n"); 76 } 77 } 78 #else 79 #define MDP(x) 80 #endif 81 82 83 84 85 86 void 87 mach_descrip_init(void) 88 { 89 uint64_t md_size, ret; 90 91 MDP(("MD: Requesting buffer size\n")); 92 93 md_size = 0LL; 94 (void) hv_mach_desc((uint64_t)0, &md_size); 95 MDP(("MD: buffer size is %d\n", md_size)); 96 97 /* 98 * Align allocated space to nearest page contig_mem_alloc_align 99 * requires a Power of 2 alignment 100 */ 101 machine_descrip.space = P2ROUNDUP(md_size, PAGESIZE); 102 MDP(("MD: allocated space is %d\n", machine_descrip.space)); 103 machine_descrip.va = contig_mem_alloc_align(machine_descrip.space, 104 PAGESIZE); 105 if (machine_descrip.va == NULL) 106 cmn_err(CE_PANIC, "Allocation for machine description failed"); 107 108 MDP(("MD: allocated va = 0x%p (size 0x%llx)\n", 109 machine_descrip.va, machine_descrip.space)); 110 111 machine_descrip.pa = va_to_pa(machine_descrip.va); 112 113 MDP(("MD: allocated pa = 0x%llx\n", machine_descrip.pa)); 114 115 ret = hv_mach_desc(machine_descrip.pa, &md_size); 116 MDP(("MD: HV return code = %ld\n", ret)); 117 118 if (ret != H_EOK) { 119 MDP(("MD: Failed with code %ld from HV\n", ret)); 120 121 machine_descrip.size = 0; 122 123 } else { 124 MDP(("MD: Grabbed %d bytes from HV\n", md_size)); 125 #ifdef MACH_DESC_DEBUG 126 dump_buf((uint8_t *)machine_descrip.va, md_size); 127 #endif /* MACH_DESC_DEBUG */ 128 129 machine_descrip.size = md_size; 130 131 /* 132 * Allocate the kstat to get at the data 133 */ 134 machine_descrip.ksp = kstat_create("unix", 0, "machdesc", 135 "misc", 136 KSTAT_TYPE_RAW, 137 (uint_t)machine_descrip.size, 138 KSTAT_FLAG_VIRTUAL); 139 140 if (machine_descrip.ksp == NULL) { 141 cmn_err(CE_PANIC, 142 "Failed to create kstat for machine description"); 143 } else { 144 machine_descrip.ksp->ks_data = machine_descrip.va; 145 kstat_install(machine_descrip.ksp); 146 } 147 } 148 } 149