/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pdevinfo.h" #include "display.h" #include "display_sun4v.h" #include "libprtdiag.h" #if !defined(TEXT_DOMAIN) #define TEXT_DOMAIN "SYS_TEST" #endif extern int sys_clk; int sun4v_display(Sys_tree *tree, Prom_node *root, int syserrlog, picl_nodehdl_t plafh) { int exit_code = 0; /* init to all OK */ void *value; /* used for opaque PROM data */ struct mem_total memory_total; /* Total memory in system */ struct grp_info grps; /* Info on all groups in system */ sys_clk = -1; /* System clock freq. (in MHz) */ /* * Now display the machine's configuration. We do this if we * are not logging. */ if (!logging) { struct utsname uts_buf; /* * Display system banner */ (void) uname(&uts_buf); log_printf( dgettext(TEXT_DOMAIN, "System Configuration: " "Sun Microsystems %s %s\n"), uts_buf.machine, get_prop_val(find_prop(root, "banner-name")), 0); /* display system clock frequency */ value = get_prop_val(find_prop(root, "clock-frequency")); if (value != NULL) { sys_clk = ((*((int *)value)) + 500000) / 1000000; log_printf(dgettext(TEXT_DOMAIN, "System clock " "frequency: %d MHz\n"), sys_clk, 0); } /* Display the Memory Size */ display_memorysize(tree, NULL, &grps, &memory_total); /* Display the CPU devices */ sun4v_display_cpu_devices(plafh); /* Display the Memory configuration */ sun4v_display_memoryconf(plafh); /* Display all the IO cards. */ (void) sun4v_display_pci(plafh); sun4v_display_diaginfo((syserrlog || (logging)), root, plafh); } return (exit_code); } /* * display_pci * Display all the PCI IO cards on this board. */ void sun4v_display_pci(picl_nodehdl_t plafh) { #ifdef lint plafh = plafh; #endif /* * This function is intentionally empty */ } void sun4v_display_memoryconf(picl_nodehdl_t plafh) { #ifdef lint plafh = plafh; #endif /* * This function is intentionally empty */ } void sun4v_display_cpu_devices(picl_nodehdl_t plafh) { char *fmt = "%-12s %-5s %-8s %-19s %-5s"; /* * Display the table header for CPUs . Then display the CPU * frequency, cache size, and processor revision of all cpus. */ log_printf(dgettext(TEXT_DOMAIN, "\n" "=========================" " CPUs " "===============================================" "\n" "\n")); log_printf(fmt, "", "", "", "CPU", "CPU", 0); log_printf("\n"); log_printf(fmt, "Location", "CPU", "Freq", "Implementation", "Mask", 0); log_printf("\n"); log_printf(fmt, "------------", "-----", "--------", "-------------------", "-----", 0); log_printf("\n"); (void) picl_walk_tree_by_class(plafh, "cpu", "cpu", sun4v_display_cpus); log_printf("\n"); } /* * Display the CPUs present on this board. */ /*ARGSUSED*/ int sun4v_display_cpus(picl_nodehdl_t cpuh, void* args) { int status; picl_prophdl_t proph; picl_prophdl_t tblh; picl_prophdl_t rowproph; picl_propinfo_t propinfo; int *int_value; uint64_t cpuid, mask_no; char *comp_value; char *no_prop_value = " "; char freq_str[MAXSTRLEN]; char fru_name[MAXSTRLEN]; /* * Get cpuid property and print it and the NAC name */ status = picl_get_propinfo_by_name(cpuh, "cpuid", &propinfo, &proph); if (status == PICL_SUCCESS) { status = picl_get_propval(proph, &cpuid, sizeof (cpuid)); if (status != PICL_SUCCESS) { log_printf("%-12s", no_prop_value); log_printf("%6s", no_prop_value); } else { (void) snprintf(fru_name, sizeof (fru_name), "%s%d", CPU_STRAND_NAC, (int)cpuid); log_printf("%-12s", fru_name); log_printf("%6d", (int)cpuid); } } else { log_printf("%-12s", no_prop_value); log_printf("%6s", no_prop_value); } clock_freq: status = picl_get_propinfo_by_name(cpuh, "clock-frequency", &propinfo, &proph); if (status == PICL_SUCCESS) { int_value = malloc(propinfo.size); if (int_value == NULL) { log_printf("%9s", no_prop_value); goto compatible; } status = picl_get_propval(proph, int_value, propinfo.size); if (status != PICL_SUCCESS) { log_printf("%9s", no_prop_value); } else { /* Running frequency */ (void) snprintf(freq_str, sizeof (freq_str), "%d MHz", CLK_FREQ_TO_MHZ(*int_value)); log_printf("%9s", freq_str); } free(int_value); } else log_printf("%9s", no_prop_value); compatible: status = picl_get_propinfo_by_name(cpuh, "compatible", &propinfo, &proph); if (status == PICL_SUCCESS) { if (propinfo.type == PICL_PTYPE_CHARSTRING) { /* * Compatible Property only has 1 value */ comp_value = malloc(propinfo.size); if (comp_value == NULL) { log_printf("%20s", no_prop_value, 0); goto mask; } status = picl_get_propval(proph, comp_value, propinfo.size); if (status == PICL_SUCCESS) { log_printf("%20s", no_prop_value, 0); free(comp_value); } } else if (propinfo.type == PICL_PTYPE_TABLE) { /* * Compatible Property has multiple values */ status = picl_get_propval(proph, &tblh, propinfo.size); if (status != PICL_SUCCESS) { printf("Failed getting tblh\n"); log_printf("%20s", no_prop_value, 0); goto mask; } status = picl_get_next_by_row(tblh, &rowproph); if (status != PICL_SUCCESS) { printf("Failed getting next by row\n"); log_printf("%20s", no_prop_value, 0); goto mask; } status = picl_get_propinfo(rowproph, &propinfo); if (status != PICL_SUCCESS) { printf("Failed getting prop for rowproph\n"); log_printf("%20s", no_prop_value, 0); goto mask; } comp_value = malloc(propinfo.size); if (comp_value == NULL) { printf("Failed to get malloc value?\n"); log_printf("%20s", no_prop_value, 0); goto mask; } status = picl_get_propval(rowproph, comp_value, propinfo.size); if (status != PICL_SUCCESS) { printf("Failed geting rowproph\n"); log_printf("%20s", no_prop_value, 0); free(comp_value); goto mask; } else log_printf("%20s", comp_value, 0); free(comp_value); } } else log_printf("%20s", no_prop_value, 0); mask: status = picl_get_propinfo_by_name(cpuh, "mask#", &propinfo, &proph); if (status == PICL_SUCCESS) { status = picl_get_propval(proph, &mask_no, sizeof (mask_no)); if (status != PICL_SUCCESS) { log_printf("%9s", no_prop_value); } else { log_printf(dgettext(TEXT_DOMAIN, " %2d.%d"), (mask_no>> 4) & 0xf, mask_no & 0xf); } } else log_printf("%9s", no_prop_value); done: log_printf("\n"); return (PICL_WALK_CONTINUE); } void sun4v_display_diaginfo(int flag, Prom_node *root, picl_nodehdl_t plafh) { #ifdef lint flag = flag; root = root; plafh = plafh; #endif /* * This function is intentionally empty */ } void display_boardnum(int num) { log_printf("%2d ", num, 0); }