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