1*03831d35Sstevel /* 2*03831d35Sstevel * CDDL HEADER START 3*03831d35Sstevel * 4*03831d35Sstevel * The contents of this file are subject to the terms of the 5*03831d35Sstevel * Common Development and Distribution License, Version 1.0 only 6*03831d35Sstevel * (the "License"). You may not use this file except in compliance 7*03831d35Sstevel * with the License. 8*03831d35Sstevel * 9*03831d35Sstevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*03831d35Sstevel * or http://www.opensolaris.org/os/licensing. 11*03831d35Sstevel * See the License for the specific language governing permissions 12*03831d35Sstevel * and limitations under the License. 13*03831d35Sstevel * 14*03831d35Sstevel * When distributing Covered Code, include this CDDL HEADER in each 15*03831d35Sstevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*03831d35Sstevel * If applicable, add the following below this CDDL HEADER, with the 17*03831d35Sstevel * fields enclosed by brackets "[]" replaced with your own identifying 18*03831d35Sstevel * information: Portions Copyright [yyyy] [name of copyright owner] 19*03831d35Sstevel * 20*03831d35Sstevel * CDDL HEADER END 21*03831d35Sstevel */ 22*03831d35Sstevel /* 23*03831d35Sstevel * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*03831d35Sstevel * Use is subject to license terms. 25*03831d35Sstevel */ 26*03831d35Sstevel #pragma ident "%Z%%M% %I% %E% SMI" 27*03831d35Sstevel 28*03831d35Sstevel #include <stdio.h> 29*03831d35Sstevel #include <stdlib.h> 30*03831d35Sstevel #include <unistd.h> 31*03831d35Sstevel #include <ctype.h> 32*03831d35Sstevel #include <string.h> 33*03831d35Sstevel #include <kvm.h> 34*03831d35Sstevel #include <varargs.h> 35*03831d35Sstevel #include <errno.h> 36*03831d35Sstevel #include <time.h> 37*03831d35Sstevel #include <dirent.h> 38*03831d35Sstevel #include <fcntl.h> 39*03831d35Sstevel #include <sys/param.h> 40*03831d35Sstevel #include <sys/stat.h> 41*03831d35Sstevel #include <sys/types.h> 42*03831d35Sstevel #include <sys/utsname.h> 43*03831d35Sstevel #include <sys/openpromio.h> 44*03831d35Sstevel #include <sys/spitregs.h> 45*03831d35Sstevel #include <sys/cheetahregs.h> 46*03831d35Sstevel #include <kstat.h> 47*03831d35Sstevel #include <libintl.h> 48*03831d35Sstevel #include <syslog.h> 49*03831d35Sstevel #include <sys/dkio.h> 50*03831d35Sstevel #include "pdevinfo.h" 51*03831d35Sstevel #include "display.h" 52*03831d35Sstevel #include "pdevinfo_sun4u.h" 53*03831d35Sstevel #include "display_sun4u.h" 54*03831d35Sstevel #include "libprtdiag.h" 55*03831d35Sstevel 56*03831d35Sstevel /* 57*03831d35Sstevel * Return the operating frequency of a processor in Hertz. This function 58*03831d35Sstevel * requires as input a legal prom node pointer. If a NULL 59*03831d35Sstevel * is passed in or the clock-frequency property does not exist, the 60*03831d35Sstevel * function returns 0. 61*03831d35Sstevel */ 62*03831d35Sstevel int 63*03831d35Sstevel get_cpu_freq(Prom_node *pnode) 64*03831d35Sstevel { 65*03831d35Sstevel Prop *prop; 66*03831d35Sstevel int *value; 67*03831d35Sstevel 68*03831d35Sstevel /* find the property */ 69*03831d35Sstevel if ((prop = find_prop(pnode, "clock-frequency")) == NULL) { 70*03831d35Sstevel return (0); 71*03831d35Sstevel } 72*03831d35Sstevel 73*03831d35Sstevel if ((value = (int *)get_prop_val(prop)) == NULL) { 74*03831d35Sstevel return (0); 75*03831d35Sstevel } 76*03831d35Sstevel 77*03831d35Sstevel return (*value); 78*03831d35Sstevel } 79*03831d35Sstevel 80*03831d35Sstevel /* 81*03831d35Sstevel * returns the size of the given processors external cache in 82*03831d35Sstevel * bytes. If the properties required to determine this are not 83*03831d35Sstevel * present, then the function returns 0. 84*03831d35Sstevel */ 85*03831d35Sstevel int 86*03831d35Sstevel get_ecache_size(Prom_node *node) 87*03831d35Sstevel { 88*03831d35Sstevel int *cache_size_p; /* pointer to number of cache lines */ 89*03831d35Sstevel 90*03831d35Sstevel /* find the properties */ 91*03831d35Sstevel if (cache_size_p = (int *)get_prop_val(find_prop(node, 92*03831d35Sstevel "ecache-size"))) { 93*03831d35Sstevel return (*cache_size_p); 94*03831d35Sstevel } 95*03831d35Sstevel if (cache_size_p = (int *)get_prop_val(find_prop(node, 96*03831d35Sstevel "l3-cache-size"))) { 97*03831d35Sstevel return (*cache_size_p); 98*03831d35Sstevel } 99*03831d35Sstevel if (cache_size_p = (int *)get_prop_val(find_prop(node, 100*03831d35Sstevel "l2-cache-size"))) { 101*03831d35Sstevel return (*cache_size_p); 102*03831d35Sstevel } 103*03831d35Sstevel 104*03831d35Sstevel return (0); 105*03831d35Sstevel } 106*03831d35Sstevel 107*03831d35Sstevel 108*03831d35Sstevel /* 109*03831d35Sstevel * This routine is the generic link into displaying CPU and memory info. 110*03831d35Sstevel * It displays the table header, then calls the CPU and memory display 111*03831d35Sstevel * routine for all boards. 112*03831d35Sstevel */ 113*03831d35Sstevel void 114*03831d35Sstevel display_cpu_devices(Sys_tree *tree) 115*03831d35Sstevel { 116*03831d35Sstevel Board_node *bnode; 117*03831d35Sstevel 118*03831d35Sstevel /* 119*03831d35Sstevel * Display the table header for CPUs . Then display the CPU 120*03831d35Sstevel * frequency, cache size, and processor revision of all cpus. 121*03831d35Sstevel */ 122*03831d35Sstevel log_printf("\n", 0); 123*03831d35Sstevel log_printf("=========================", 0); 124*03831d35Sstevel log_printf(" CPUs ", 0); 125*03831d35Sstevel log_printf("=========================", 0); 126*03831d35Sstevel log_printf("\n", 0); 127*03831d35Sstevel log_printf("\n", 0); 128*03831d35Sstevel log_printf(" Run Ecache " 129*03831d35Sstevel " CPU CPU\n", 0); 130*03831d35Sstevel log_printf("Brd CPU Module MHz MB " 131*03831d35Sstevel "Impl. Mask\n", 0); 132*03831d35Sstevel log_printf("--- --- ------- ----- ------ " 133*03831d35Sstevel "------ ----\n", 0); 134*03831d35Sstevel 135*03831d35Sstevel /* Now display all of the cpus on each board */ 136*03831d35Sstevel bnode = tree->bd_list; 137*03831d35Sstevel while (bnode != NULL) { 138*03831d35Sstevel display_cpus(bnode); 139*03831d35Sstevel bnode = bnode->next; 140*03831d35Sstevel } 141*03831d35Sstevel 142*03831d35Sstevel log_printf("\n", 0); 143*03831d35Sstevel } 144*03831d35Sstevel 145*03831d35Sstevel /* 146*03831d35Sstevel * Display the CPUs present on this board. 147*03831d35Sstevel */ 148*03831d35Sstevel void 149*03831d35Sstevel display_cpus(Board_node *board) 150*03831d35Sstevel { 151*03831d35Sstevel Prom_node *cpu; 152*03831d35Sstevel 153*03831d35Sstevel /* 154*03831d35Sstevel * display the CPUs' operating frequency, cache size, impl. field 155*03831d35Sstevel * and mask revision. 156*03831d35Sstevel */ 157*03831d35Sstevel for (cpu = dev_find_type(board->nodes, "cpu"); cpu != NULL; 158*03831d35Sstevel cpu = dev_next_type(cpu, "cpu")) { 159*03831d35Sstevel int freq; /* CPU clock frequency */ 160*03831d35Sstevel int ecache_size; /* External cache size */ 161*03831d35Sstevel int *mid; 162*03831d35Sstevel int *impl; 163*03831d35Sstevel int *mask, decoded_mask; 164*03831d35Sstevel 165*03831d35Sstevel mid = (int *)get_prop_val(find_prop(cpu, "upa-portid")); 166*03831d35Sstevel if (mid == NULL) { 167*03831d35Sstevel mid = (int *)get_prop_val(find_prop(cpu, "portid")); 168*03831d35Sstevel } 169*03831d35Sstevel 170*03831d35Sstevel freq = (get_cpu_freq(cpu) + 500000) / 1000000; 171*03831d35Sstevel ecache_size = get_ecache_size(cpu); 172*03831d35Sstevel impl = (int *)get_prop_val(find_prop(cpu, "implementation#")); 173*03831d35Sstevel mask = (int *)get_prop_val(find_prop(cpu, "mask#")); 174*03831d35Sstevel 175*03831d35Sstevel /* Do not display a failed CPU node */ 176*03831d35Sstevel if ((freq != 0) && (node_failed(cpu) == 0)) { 177*03831d35Sstevel /* Board number */ 178*03831d35Sstevel display_boardnum(board->board_num); 179*03831d35Sstevel 180*03831d35Sstevel /* CPU MID */ 181*03831d35Sstevel log_printf(" %2d ", *mid, 0); 182*03831d35Sstevel 183*03831d35Sstevel /* Module number */ 184*03831d35Sstevel display_mid(*mid); 185*03831d35Sstevel 186*03831d35Sstevel /* Running frequency */ 187*03831d35Sstevel log_printf(" %3d ", freq, 0); 188*03831d35Sstevel 189*03831d35Sstevel /* Ecache size */ 190*03831d35Sstevel if (ecache_size == 0) 191*03831d35Sstevel log_printf(" %3s ", "N/A", 0); 192*03831d35Sstevel else 193*03831d35Sstevel log_printf(" %4.1f ", 194*03831d35Sstevel (float)ecache_size / (float)(1<<20), 195*03831d35Sstevel 0); 196*03831d35Sstevel 197*03831d35Sstevel /* Implementation */ 198*03831d35Sstevel if (impl == NULL) { 199*03831d35Sstevel log_printf("%6s ", "N/A", 0); 200*03831d35Sstevel } else { 201*03831d35Sstevel switch (*impl) { 202*03831d35Sstevel case SPITFIRE_IMPL: 203*03831d35Sstevel log_printf("%-6s ", "US-I", 0); 204*03831d35Sstevel break; 205*03831d35Sstevel case BLACKBIRD_IMPL: 206*03831d35Sstevel log_printf("%-6s ", "US-II", 0); 207*03831d35Sstevel break; 208*03831d35Sstevel case CHEETAH_IMPL: 209*03831d35Sstevel log_printf("%-6s ", "US-III", 0); 210*03831d35Sstevel break; 211*03831d35Sstevel case CHEETAH_PLUS_IMPL: 212*03831d35Sstevel log_printf("%-7s ", "US-III+", 0); 213*03831d35Sstevel break; 214*03831d35Sstevel case JAGUAR_IMPL: 215*03831d35Sstevel log_printf("%-6s ", "US-IV", 0); 216*03831d35Sstevel break; 217*03831d35Sstevel default: 218*03831d35Sstevel log_printf("%-6x ", *impl, 0); 219*03831d35Sstevel break; 220*03831d35Sstevel } 221*03831d35Sstevel } 222*03831d35Sstevel 223*03831d35Sstevel /* CPU Mask */ 224*03831d35Sstevel if (mask == NULL) { 225*03831d35Sstevel log_printf(" %3s", "N/A", 0); 226*03831d35Sstevel } else { 227*03831d35Sstevel if ((impl) && IS_CHEETAH(*impl)) 228*03831d35Sstevel decoded_mask = 229*03831d35Sstevel REMAP_CHEETAH_MASK(*mask); 230*03831d35Sstevel else 231*03831d35Sstevel decoded_mask = *mask; 232*03831d35Sstevel 233*03831d35Sstevel log_printf(" %d.%d", (decoded_mask >> 4) & 0xf, 234*03831d35Sstevel decoded_mask & 0xf, 0); 235*03831d35Sstevel } 236*03831d35Sstevel 237*03831d35Sstevel log_printf("\n", 0); 238*03831d35Sstevel } 239*03831d35Sstevel } 240*03831d35Sstevel } 241*03831d35Sstevel 242*03831d35Sstevel void 243*03831d35Sstevel display_mid(int mid) 244*03831d35Sstevel { 245*03831d35Sstevel log_printf(" %2d ", mid, 0); 246*03831d35Sstevel } 247