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