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 <stdio.h> 30 #include <stdlib.h> 31 #include <unistd.h> 32 #include <ctype.h> 33 #include <string.h> 34 #include <kvm.h> 35 #include <varargs.h> 36 #include <time.h> 37 #include <dirent.h> 38 #include <fcntl.h> 39 #include <sys/param.h> 40 #include <sys/stat.h> 41 #include <sys/types.h> 42 #include <sys/utsname.h> 43 #include <sys/openpromio.h> 44 #include <libintl.h> 45 #include <syslog.h> 46 #include <sys/dkio.h> 47 #include "pdevinfo.h" 48 #include "display.h" 49 #include "display_sun4v.h" 50 #include "libprtdiag.h" 51 52 53 #if !defined(TEXT_DOMAIN) 54 #define TEXT_DOMAIN "SYS_TEST" 55 #endif 56 57 extern int sys_clk; 58 59 int 60 sun4v_display(Sys_tree *tree, Prom_node *root, int syserrlog, 61 picl_nodehdl_t plafh) 62 { 63 int exit_code = 0; /* init to all OK */ 64 void *value; /* used for opaque PROM data */ 65 struct mem_total memory_total; /* Total memory in system */ 66 struct grp_info grps; /* Info on all groups in system */ 67 68 sys_clk = -1; /* System clock freq. (in MHz) */ 69 70 /* 71 * Now display the machine's configuration. We do this if we 72 * are not logging. 73 */ 74 if (!logging) { 75 struct utsname uts_buf; 76 77 /* 78 * Display system banner 79 */ 80 (void) uname(&uts_buf); 81 82 log_printf( 83 dgettext(TEXT_DOMAIN, "System Configuration: " 84 "Sun Microsystems %s %s\n"), uts_buf.machine, 85 get_prop_val(find_prop(root, 86 "banner-name")), 0); 87 88 /* display system clock frequency */ 89 value = get_prop_val(find_prop(root, "clock-frequency")); 90 if (value != NULL) { 91 sys_clk = ((*((int *)value)) + 500000) / 1000000; 92 log_printf(dgettext(TEXT_DOMAIN, "System clock " 93 "frequency: %d MHz\n"), sys_clk, 0); 94 } 95 96 /* Display the Memory Size */ 97 display_memorysize(tree, NULL, &grps, &memory_total); 98 99 /* Display the CPU devices */ 100 sun4v_display_cpu_devices(plafh); 101 102 /* Display the Memory configuration */ 103 sun4v_display_memoryconf(plafh); 104 105 /* Display all the IO cards. */ 106 (void) sun4v_display_pci(plafh); 107 108 sun4v_display_diaginfo((syserrlog || (logging)), root, plafh); 109 } 110 111 return (exit_code); 112 } 113 114 /* 115 * display_pci 116 * Display all the PCI IO cards on this board. 117 */ 118 void 119 sun4v_display_pci(picl_nodehdl_t plafh) 120 { 121 #ifdef lint 122 plafh = plafh; 123 #endif 124 /* 125 * This function is intentionally empty 126 */ 127 } 128 129 void 130 sun4v_display_memoryconf(picl_nodehdl_t plafh) 131 { 132 #ifdef lint 133 plafh = plafh; 134 #endif 135 /* 136 * This function is intentionally empty 137 */ 138 } 139 140 void 141 sun4v_display_cpu_devices(picl_nodehdl_t plafh) 142 { 143 char *fmt = "%-12s %-5s %-8s %-19s %-5s"; 144 145 /* 146 * Display the table header for CPUs . Then display the CPU 147 * frequency, cache size, and processor revision of all cpus. 148 */ 149 log_printf(dgettext(TEXT_DOMAIN, 150 "\n" 151 "=========================" 152 " CPUs " 153 "===============================================" 154 "\n" 155 "\n")); 156 log_printf(fmt, "", "", "", "CPU", "CPU", 0); 157 log_printf("\n"); 158 log_printf(fmt, "Location", "CPU", "Freq", 159 "Implementation", "Mask", 0); 160 log_printf("\n"); 161 log_printf(fmt, "------------", "-----", "--------", 162 "-------------------", "-----", 0); 163 log_printf("\n"); 164 165 (void) picl_walk_tree_by_class(plafh, "cpu", "cpu", sun4v_display_cpus); 166 167 log_printf("\n"); 168 } 169 170 /* 171 * Display the CPUs present on this board. 172 */ 173 /*ARGSUSED*/ 174 int 175 sun4v_display_cpus(picl_nodehdl_t cpuh, void* args) 176 { 177 int status; 178 picl_prophdl_t proph; 179 picl_prophdl_t tblh; 180 picl_prophdl_t rowproph; 181 picl_propinfo_t propinfo; 182 int *int_value; 183 uint64_t cpuid, mask_no; 184 char *comp_value; 185 char *no_prop_value = " "; 186 char freq_str[MAXSTRLEN]; 187 char fru_name[MAXSTRLEN]; 188 189 /* 190 * Get cpuid property and print it and the NAC name 191 */ 192 status = picl_get_propinfo_by_name(cpuh, "cpuid", &propinfo, &proph); 193 if (status == PICL_SUCCESS) { 194 status = picl_get_propval(proph, &cpuid, sizeof (cpuid)); 195 if (status != PICL_SUCCESS) { 196 log_printf("%-12s", no_prop_value); 197 log_printf("%6s", no_prop_value); 198 } else { 199 (void) snprintf(fru_name, sizeof (fru_name), "%s%d", 200 CPU_STRAND_NAC, (int)cpuid); 201 log_printf("%-12s", fru_name); 202 log_printf("%6d", (int)cpuid); 203 } 204 } else { 205 log_printf("%-12s", no_prop_value); 206 log_printf("%6s", no_prop_value); 207 } 208 209 clock_freq: 210 status = picl_get_propinfo_by_name(cpuh, "clock-frequency", &propinfo, 211 &proph); 212 if (status == PICL_SUCCESS) { 213 int_value = malloc(propinfo.size); 214 if (int_value == NULL) { 215 log_printf("%9s", no_prop_value); 216 goto compatible; 217 } 218 status = picl_get_propval(proph, int_value, propinfo.size); 219 if (status != PICL_SUCCESS) { 220 log_printf("%9s", no_prop_value); 221 } else { 222 /* Running frequency */ 223 (void) snprintf(freq_str, sizeof (freq_str), "%d MHz", 224 CLK_FREQ_TO_MHZ(*int_value)); 225 log_printf("%9s", freq_str); 226 } 227 free(int_value); 228 } else 229 log_printf("%9s", no_prop_value); 230 231 compatible: 232 status = picl_get_propinfo_by_name(cpuh, "compatible", &propinfo, 233 &proph); 234 if (status == PICL_SUCCESS) { 235 if (propinfo.type == PICL_PTYPE_CHARSTRING) { 236 /* 237 * Compatible Property only has 1 value 238 */ 239 comp_value = malloc(propinfo.size); 240 if (comp_value == NULL) { 241 log_printf("%20s", no_prop_value, 0); 242 goto mask; 243 } 244 status = picl_get_propval(proph, comp_value, 245 propinfo.size); 246 if (status == PICL_SUCCESS) { 247 log_printf("%20s", no_prop_value, 0); 248 free(comp_value); 249 } 250 } else if (propinfo.type == PICL_PTYPE_TABLE) { 251 /* 252 * Compatible Property has multiple values 253 */ 254 status = picl_get_propval(proph, &tblh, propinfo.size); 255 if (status != PICL_SUCCESS) { 256 printf("Failed getting tblh\n"); 257 log_printf("%20s", no_prop_value, 0); 258 goto mask; 259 } 260 status = picl_get_next_by_row(tblh, &rowproph); 261 if (status != PICL_SUCCESS) { 262 printf("Failed getting next by row\n"); 263 log_printf("%20s", no_prop_value, 0); 264 goto mask; 265 } 266 267 status = picl_get_propinfo(rowproph, &propinfo); 268 if (status != PICL_SUCCESS) { 269 printf("Failed getting prop for rowproph\n"); 270 log_printf("%20s", no_prop_value, 0); 271 goto mask; 272 } 273 274 comp_value = malloc(propinfo.size); 275 if (comp_value == NULL) { 276 printf("Failed to get malloc value?\n"); 277 log_printf("%20s", no_prop_value, 0); 278 goto mask; 279 } 280 281 status = picl_get_propval(rowproph, comp_value, 282 propinfo.size); 283 if (status != PICL_SUCCESS) { 284 printf("Failed geting rowproph\n"); 285 log_printf("%20s", no_prop_value, 0); 286 free(comp_value); 287 goto mask; 288 } else 289 log_printf("%20s", comp_value, 0); 290 free(comp_value); 291 } 292 } else 293 log_printf("%20s", no_prop_value, 0); 294 295 mask: 296 status = picl_get_propinfo_by_name(cpuh, "mask#", &propinfo, &proph); 297 if (status == PICL_SUCCESS) { 298 status = picl_get_propval(proph, &mask_no, sizeof (mask_no)); 299 if (status != PICL_SUCCESS) { 300 log_printf("%9s", no_prop_value); 301 } else { 302 log_printf(dgettext(TEXT_DOMAIN, " %2d.%d"), 303 (mask_no>> 4) & 0xf, mask_no & 0xf); 304 } 305 } else 306 log_printf("%9s", no_prop_value); 307 308 done: 309 log_printf("\n"); 310 return (PICL_WALK_CONTINUE); 311 } 312 313 void 314 sun4v_display_diaginfo(int flag, Prom_node *root, picl_nodehdl_t plafh) 315 { 316 #ifdef lint 317 flag = flag; 318 root = root; 319 plafh = plafh; 320 #endif 321 /* 322 * This function is intentionally empty 323 */ 324 } 325 326 void 327 display_boardnum(int num) 328 { 329 log_printf("%2d ", num, 0); 330 } 331