17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 237c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #include <sys/types.h> 307c478bd9Sstevel@tonic-gate #include <string.h> 317c478bd9Sstevel@tonic-gate #include <alloca.h> 327c478bd9Sstevel@tonic-gate #include <stdlib.h> 337c478bd9Sstevel@tonic-gate #include <stdio.h> 347c478bd9Sstevel@tonic-gate #include <libintl.h> 357c478bd9Sstevel@tonic-gate #include <libdevinfo.h> 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate #include "libcpc.h" 387c478bd9Sstevel@tonic-gate #include "libcpc_impl.h" 397c478bd9Sstevel@tonic-gate 407c478bd9Sstevel@tonic-gate /* 417c478bd9Sstevel@tonic-gate * Configuration data for UltraSPARC performance counters. 427c478bd9Sstevel@tonic-gate * 43*23961e2bSvb70745 * Definitions taken from [1], [2], [3] [4] and [5]. See the references to 447c478bd9Sstevel@tonic-gate * understand what any of these settings actually means. 457c478bd9Sstevel@tonic-gate * 467c478bd9Sstevel@tonic-gate * Note that in the current draft of [2], there is some re-use 477c478bd9Sstevel@tonic-gate * of existing bit assignments in the various fields of the %pcr 487c478bd9Sstevel@tonic-gate * register - this may change before FCS. 497c478bd9Sstevel@tonic-gate * 507c478bd9Sstevel@tonic-gate * The following are the Internal Documents. Customers need to be 517c478bd9Sstevel@tonic-gate * told about the Public docs in cpc_getcpuref(). 527c478bd9Sstevel@tonic-gate * [1] "UltraSPARC I & II User's Manual," January 1997. 537c478bd9Sstevel@tonic-gate * [2] "UltraSPARC-III Programmer's Reference Manual," April 1999. 547c478bd9Sstevel@tonic-gate * [3] "Cheetah+ Programmer's Reference Manual," November 2000. 557c478bd9Sstevel@tonic-gate * [4] "UltraSPARC-IIIi Programmer's Reference Manual," November 2000. 56*23961e2bSvb70745 * [5] "UltraSPARC-IV+ Programmer's Reference Manual," October 2004. 577c478bd9Sstevel@tonic-gate */ 587c478bd9Sstevel@tonic-gate 597c478bd9Sstevel@tonic-gate #define V_US12 (1u << 0) /* specific to UltraSPARC 1 and 2 */ 607c478bd9Sstevel@tonic-gate #define V_US3 (1u << 1) /* specific to UltraSPARC 3 */ 617c478bd9Sstevel@tonic-gate #define V_US3_PLUS (1u << 2) /* specific to UltraSPARC 3 PLUS */ 627c478bd9Sstevel@tonic-gate #define V_US3_I (1u << 3) /* specific to UltraSPARC-IIIi */ 63*23961e2bSvb70745 #define V_US4_PLUS (1u << 4) /* specific to UltraSPARC-IV+ */ 647c478bd9Sstevel@tonic-gate #define V_END (1u << 31) 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate /* 677c478bd9Sstevel@tonic-gate * map from "cpu version" to flag bits 687c478bd9Sstevel@tonic-gate */ 697c478bd9Sstevel@tonic-gate static const uint_t cpuvermap[] = { 707c478bd9Sstevel@tonic-gate V_US12, /* CPC_ULTRA1 */ 717c478bd9Sstevel@tonic-gate V_US12, /* CPC_ULTRA2 */ 727c478bd9Sstevel@tonic-gate V_US3, /* CPC_ULTRA3 */ 737c478bd9Sstevel@tonic-gate V_US3_PLUS, /* CPC_ULTRA3_PLUS */ 74*23961e2bSvb70745 V_US3_I, /* CPC_ULTRA3I */ 75*23961e2bSvb70745 V_US4_PLUS /* CPC_ULTRA4_PLUS */ 767c478bd9Sstevel@tonic-gate }; 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate struct nametable { 797c478bd9Sstevel@tonic-gate const uint_t ver; 807c478bd9Sstevel@tonic-gate const uint8_t bits; 817c478bd9Sstevel@tonic-gate const char *name; 827c478bd9Sstevel@tonic-gate }; 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate /* 857c478bd9Sstevel@tonic-gate * Definitions for counter 0 867c478bd9Sstevel@tonic-gate */ 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate #define USall_EVENTS_0(v) \ 897c478bd9Sstevel@tonic-gate {v, 0x0, "Cycle_cnt"}, \ 907c478bd9Sstevel@tonic-gate {v, 0x1, "Instr_cnt"}, \ 917c478bd9Sstevel@tonic-gate {v, 0x2, "Dispatch0_IC_miss"}, \ 927c478bd9Sstevel@tonic-gate {v, 0x8, "IC_ref"}, \ 937c478bd9Sstevel@tonic-gate {v, 0x9, "DC_rd"}, \ 947c478bd9Sstevel@tonic-gate {v, 0xa, "DC_wr"}, \ 957c478bd9Sstevel@tonic-gate {v, 0xc, "EC_ref"}, \ 967c478bd9Sstevel@tonic-gate {v, 0xe, "EC_snoop_inv"} 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate static const struct nametable US12_names0[] = { 997c478bd9Sstevel@tonic-gate USall_EVENTS_0(V_US12), 1007c478bd9Sstevel@tonic-gate {V_US12, 0x3, "Dispatch0_storeBuf"}, 1017c478bd9Sstevel@tonic-gate {V_US12, 0xb, "Load_use"}, 1027c478bd9Sstevel@tonic-gate {V_US12, 0xd, "EC_write_hit_RDO"}, 1037c478bd9Sstevel@tonic-gate {V_US12, 0xf, "EC_rd_hit"}, 1047c478bd9Sstevel@tonic-gate {V_END} 1057c478bd9Sstevel@tonic-gate }; 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate #define US3all_EVENTS_0(v) \ 1087c478bd9Sstevel@tonic-gate {v, 0x3, "Dispatch0_br_target"}, \ 1097c478bd9Sstevel@tonic-gate {v, 0x4, "Dispatch0_2nd_br"}, \ 1107c478bd9Sstevel@tonic-gate {v, 0x5, "Rstall_storeQ"}, \ 1117c478bd9Sstevel@tonic-gate {v, 0x6, "Rstall_IU_use"}, \ 1127c478bd9Sstevel@tonic-gate {v, 0xd, "EC_write_hit_RTO"}, \ 1137c478bd9Sstevel@tonic-gate {v, 0xf, "EC_rd_miss"}, \ 1147c478bd9Sstevel@tonic-gate {v, 0x10, "PC_port0_rd"}, \ 1157c478bd9Sstevel@tonic-gate {v, 0x11, "SI_snoop"}, \ 1167c478bd9Sstevel@tonic-gate {v, 0x12, "SI_ciq_flow"}, \ 1177c478bd9Sstevel@tonic-gate {v, 0x13, "SI_owned"}, \ 1187c478bd9Sstevel@tonic-gate {v, 0x14, "SW_count_0"}, \ 1197c478bd9Sstevel@tonic-gate {v, 0x15, "IU_Stat_Br_miss_taken"}, \ 1207c478bd9Sstevel@tonic-gate {v, 0x16, "IU_Stat_Br_count_taken"}, \ 1217c478bd9Sstevel@tonic-gate {v, 0x17, "Dispatch_rs_mispred"}, \ 1227c478bd9Sstevel@tonic-gate {v, 0x18, "FA_pipe_completion"} 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate #define US3_MC_EVENTS_0(v) \ 1257c478bd9Sstevel@tonic-gate {v, 0x20, "MC_reads_0"}, \ 1267c478bd9Sstevel@tonic-gate {v, 0x21, "MC_reads_1"}, \ 1277c478bd9Sstevel@tonic-gate {v, 0x22, "MC_reads_2"}, \ 1287c478bd9Sstevel@tonic-gate {v, 0x23, "MC_reads_3"}, \ 1297c478bd9Sstevel@tonic-gate {v, 0x24, "MC_stalls_0"}, \ 1307c478bd9Sstevel@tonic-gate {v, 0x25, "MC_stalls_2"} 1317c478bd9Sstevel@tonic-gate 1327c478bd9Sstevel@tonic-gate #define US3_I_MC_EVENTS_0(v) \ 1337c478bd9Sstevel@tonic-gate {v, 0x20, "MC_read_dispatched"}, \ 1347c478bd9Sstevel@tonic-gate {v, 0x21, "MC_write_dispatched"}, \ 1357c478bd9Sstevel@tonic-gate {v, 0x22, "MC_read_returned_to_JBU"}, \ 1367c478bd9Sstevel@tonic-gate {v, 0x23, "MC_msl_busy_stall"}, \ 1377c478bd9Sstevel@tonic-gate {v, 0x24, "MC_mdb_overflow_stall"}, \ 1387c478bd9Sstevel@tonic-gate {v, 0x25, "MC_miu_spec_request"} 1397c478bd9Sstevel@tonic-gate 1407c478bd9Sstevel@tonic-gate static const struct nametable US3_names0[] = { 1417c478bd9Sstevel@tonic-gate USall_EVENTS_0(V_US3), 1427c478bd9Sstevel@tonic-gate US3all_EVENTS_0(V_US3), 1437c478bd9Sstevel@tonic-gate US3_MC_EVENTS_0(V_US3), 1447c478bd9Sstevel@tonic-gate {V_END} 1457c478bd9Sstevel@tonic-gate }; 1467c478bd9Sstevel@tonic-gate 147*23961e2bSvb70745 static const struct nametable US4_PLUS_names0[] = { 148*23961e2bSvb70745 {V_US4_PLUS, 0x0, "Cycle_cnt"}, 149*23961e2bSvb70745 {V_US4_PLUS, 0x1, "Instr_cnt"}, 150*23961e2bSvb70745 {V_US4_PLUS, 0x2, "Dispatch0_IC_miss"}, 151*23961e2bSvb70745 {V_US4_PLUS, 0x3, "IU_stat_jmp_correct_pred"}, 152*23961e2bSvb70745 {V_US4_PLUS, 0x4, "Dispatch0_2nd_br"}, 153*23961e2bSvb70745 {V_US4_PLUS, 0x5, "Rstall_storeQ"}, 154*23961e2bSvb70745 {V_US4_PLUS, 0x6, "Rstall_IU_use"}, 155*23961e2bSvb70745 {V_US4_PLUS, 0x7, "IU_stat_ret_correct_pred"}, 156*23961e2bSvb70745 {V_US4_PLUS, 0x8, "IC_ref"}, 157*23961e2bSvb70745 {V_US4_PLUS, 0x9, "DC_rd"}, 158*23961e2bSvb70745 {V_US4_PLUS, 0xa, "Rstall_FP_use"}, 159*23961e2bSvb70745 {V_US4_PLUS, 0xb, "SW_pf_instr"}, 160*23961e2bSvb70745 {V_US4_PLUS, 0xc, "L2_ref"}, 161*23961e2bSvb70745 {V_US4_PLUS, 0xd, "L2_write_hit_RTO"}, 162*23961e2bSvb70745 {V_US4_PLUS, 0xe, "L2_snoop_inv_sh"}, 163*23961e2bSvb70745 {V_US4_PLUS, 0xf, "L2_rd_miss"}, 164*23961e2bSvb70745 {V_US4_PLUS, 0x10, "PC_rd"}, 165*23961e2bSvb70745 {V_US4_PLUS, 0x11, "SI_snoop_sh"}, 166*23961e2bSvb70745 {V_US4_PLUS, 0x12, "SI_ciq_flow_sh"}, 167*23961e2bSvb70745 {V_US4_PLUS, 0x13, "Re_DC_miss"}, 168*23961e2bSvb70745 {V_US4_PLUS, 0x14, "SW_count_NOP"}, 169*23961e2bSvb70745 {V_US4_PLUS, 0x15, "IU_stat_br_miss_taken"}, 170*23961e2bSvb70745 {V_US4_PLUS, 0x16, "IU_stat_br_count_untaken"}, 171*23961e2bSvb70745 {V_US4_PLUS, 0x17, "HW_pf_exec"}, 172*23961e2bSvb70745 {V_US4_PLUS, 0x18, "FA_pipe_completion"}, 173*23961e2bSvb70745 {V_US4_PLUS, 0x19, "SSM_L3_wb_remote"}, 174*23961e2bSvb70745 {V_US4_PLUS, 0x1a, "SSM_L3_miss_local"}, 175*23961e2bSvb70745 {V_US4_PLUS, 0x1b, "SSM_L3_miss_mtag_remote"}, 176*23961e2bSvb70745 {V_US4_PLUS, 0x1c, "SW_pf_str_trapped"}, 177*23961e2bSvb70745 {V_US4_PLUS, 0x1d, "SW_pf_PC_installed"}, 178*23961e2bSvb70745 {V_US4_PLUS, 0x1e, "IPB_to_IC_fill"}, 179*23961e2bSvb70745 {V_US4_PLUS, 0x1f, "L2_write_miss"}, 180*23961e2bSvb70745 {V_US4_PLUS, 0x20, "MC_reads_0_sh"}, 181*23961e2bSvb70745 {V_US4_PLUS, 0x21, "MC_reads_1_sh"}, 182*23961e2bSvb70745 {V_US4_PLUS, 0x22, "MC_reads_2_sh"}, 183*23961e2bSvb70745 {V_US4_PLUS, 0x23, "MC_reads_3_sh"}, 184*23961e2bSvb70745 {V_US4_PLUS, 0x24, "MC_stalls_0_sh"}, 185*23961e2bSvb70745 {V_US4_PLUS, 0x25, "MC_stalls_2_sh"}, 186*23961e2bSvb70745 {V_US4_PLUS, 0x26, "L2_hit_other_half"}, 187*23961e2bSvb70745 {V_US4_PLUS, 0x28, "L3_rd_miss"}, 188*23961e2bSvb70745 {V_US4_PLUS, 0x29, "Re_L2_miss"}, 189*23961e2bSvb70745 {V_US4_PLUS, 0x2a, "IC_miss_cancelled"}, 190*23961e2bSvb70745 {V_US4_PLUS, 0x2b, "DC_wr_miss"}, 191*23961e2bSvb70745 {V_US4_PLUS, 0x2c, "L3_hit_I_state_sh"}, 192*23961e2bSvb70745 {V_US4_PLUS, 0x2d, "SI_RTS_src_data"}, 193*23961e2bSvb70745 {V_US4_PLUS, 0x2e, "L2_IC_miss"}, 194*23961e2bSvb70745 {V_US4_PLUS, 0x2f, "SSM_new_transaction_sh"}, 195*23961e2bSvb70745 {V_US4_PLUS, 0x30, "L2_SW_pf_miss"}, 196*23961e2bSvb70745 {V_US4_PLUS, 0x31, "L2_wb"}, 197*23961e2bSvb70745 {V_US4_PLUS, 0x32, "L2_wb_sh"}, 198*23961e2bSvb70745 {V_US4_PLUS, 0x33, "L2_snoop_cb_sh"}, 199*23961e2bSvb70745 {V_END} 200*23961e2bSvb70745 }; 201*23961e2bSvb70745 2027c478bd9Sstevel@tonic-gate static const struct nametable US3_PLUS_names0[] = { 2037c478bd9Sstevel@tonic-gate USall_EVENTS_0(V_US3_PLUS), 2047c478bd9Sstevel@tonic-gate US3all_EVENTS_0(V_US3_PLUS), 2057c478bd9Sstevel@tonic-gate US3_MC_EVENTS_0(V_US3_PLUS), 2067c478bd9Sstevel@tonic-gate {V_US3_PLUS, 0x19, "EC_wb_remote"}, 2077c478bd9Sstevel@tonic-gate {V_US3_PLUS, 0x1a, "EC_miss_local"}, 2087c478bd9Sstevel@tonic-gate {V_US3_PLUS, 0x1b, "EC_miss_mtag_remote"}, 2097c478bd9Sstevel@tonic-gate {V_END} 2107c478bd9Sstevel@tonic-gate }; 2117c478bd9Sstevel@tonic-gate 2127c478bd9Sstevel@tonic-gate static const struct nametable US3_I_names0[] = { 2137c478bd9Sstevel@tonic-gate USall_EVENTS_0(V_US3_I), 2147c478bd9Sstevel@tonic-gate US3all_EVENTS_0(V_US3_I), 2157c478bd9Sstevel@tonic-gate US3_I_MC_EVENTS_0(V_US3_I), 2167c478bd9Sstevel@tonic-gate {V_US3_PLUS, 0x19, "EC_wb_remote"}, 2177c478bd9Sstevel@tonic-gate {V_US3_PLUS, 0x1a, "EC_miss_local"}, 2187c478bd9Sstevel@tonic-gate {V_US3_PLUS, 0x1b, "EC_miss_mtag_remote"}, 2197c478bd9Sstevel@tonic-gate {V_END} 2207c478bd9Sstevel@tonic-gate }; 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate #undef USall_EVENTS_0 2237c478bd9Sstevel@tonic-gate #undef US3all_EVENTS_0 2247c478bd9Sstevel@tonic-gate 2257c478bd9Sstevel@tonic-gate #define USall_EVENTS_1(v) \ 2267c478bd9Sstevel@tonic-gate {v, 0x0, "Cycle_cnt"}, \ 2277c478bd9Sstevel@tonic-gate {v, 0x1, "Instr_cnt"}, \ 2287c478bd9Sstevel@tonic-gate {v, 0x2, "Dispatch0_mispred"}, \ 2297c478bd9Sstevel@tonic-gate {v, 0xd, "EC_wb"}, \ 2307c478bd9Sstevel@tonic-gate {v, 0xe, "EC_snoop_cb"} 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate static const struct nametable US12_names1[] = { 2337c478bd9Sstevel@tonic-gate USall_EVENTS_1(V_US12), 2347c478bd9Sstevel@tonic-gate {V_US12, 0x3, "Dispatch0_FP_use"}, 2357c478bd9Sstevel@tonic-gate {V_US12, 0x8, "IC_hit"}, 2367c478bd9Sstevel@tonic-gate {V_US12, 0x9, "DC_rd_hit"}, 2377c478bd9Sstevel@tonic-gate {V_US12, 0xa, "DC_wr_hit"}, 2387c478bd9Sstevel@tonic-gate {V_US12, 0xb, "Load_use_RAW"}, 2397c478bd9Sstevel@tonic-gate {V_US12, 0xc, "EC_hit"}, 2407c478bd9Sstevel@tonic-gate {V_US12, 0xf, "EC_ic_hit"}, 2417c478bd9Sstevel@tonic-gate {V_END} 2427c478bd9Sstevel@tonic-gate }; 2437c478bd9Sstevel@tonic-gate 2447c478bd9Sstevel@tonic-gate #define US3all_EVENTS_1(v) \ 2457c478bd9Sstevel@tonic-gate {v, 0x3, "IC_miss_cancelled"}, \ 2467c478bd9Sstevel@tonic-gate {v, 0x5, "Re_FPU_bypass"}, \ 2477c478bd9Sstevel@tonic-gate {v, 0x6, "Re_DC_miss"}, \ 2487c478bd9Sstevel@tonic-gate {v, 0x7, "Re_EC_miss"}, \ 2497c478bd9Sstevel@tonic-gate {v, 0x8, "IC_miss"}, \ 2507c478bd9Sstevel@tonic-gate {v, 0x9, "DC_rd_miss"}, \ 2517c478bd9Sstevel@tonic-gate {v, 0xa, "DC_wr_miss"}, \ 2527c478bd9Sstevel@tonic-gate {v, 0xb, "Rstall_FP_use"}, \ 2537c478bd9Sstevel@tonic-gate {v, 0xc, "EC_misses"}, \ 2547c478bd9Sstevel@tonic-gate {v, 0xf, "EC_ic_miss"}, \ 2557c478bd9Sstevel@tonic-gate {v, 0x10, "Re_PC_miss"}, \ 2567c478bd9Sstevel@tonic-gate {v, 0x11, "ITLB_miss"}, \ 2577c478bd9Sstevel@tonic-gate {v, 0x12, "DTLB_miss"}, \ 2587c478bd9Sstevel@tonic-gate {v, 0x13, "WC_miss"}, \ 2597c478bd9Sstevel@tonic-gate {v, 0x14, "WC_snoop_cb"}, \ 2607c478bd9Sstevel@tonic-gate {v, 0x15, "WC_scrubbed"}, \ 2617c478bd9Sstevel@tonic-gate {v, 0x16, "WC_wb_wo_read"}, \ 2627c478bd9Sstevel@tonic-gate {v, 0x18, "PC_soft_hit"}, \ 2637c478bd9Sstevel@tonic-gate {v, 0x19, "PC_snoop_inv"}, \ 2647c478bd9Sstevel@tonic-gate {v, 0x1a, "PC_hard_hit"}, \ 2657c478bd9Sstevel@tonic-gate {v, 0x1b, "PC_port1_rd"}, \ 2667c478bd9Sstevel@tonic-gate {v, 0x1c, "SW_count_1"}, \ 2677c478bd9Sstevel@tonic-gate {v, 0x1d, "IU_Stat_Br_miss_untaken"}, \ 2687c478bd9Sstevel@tonic-gate {v, 0x1e, "IU_Stat_Br_count_untaken"}, \ 2697c478bd9Sstevel@tonic-gate {v, 0x1f, "PC_MS_misses"}, \ 2707c478bd9Sstevel@tonic-gate {v, 0x26, "Re_RAW_miss"}, \ 2717c478bd9Sstevel@tonic-gate {v, 0x27, "FM_pipe_completion"} 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate #define US3_MC_EVENTS_1(v) \ 2747c478bd9Sstevel@tonic-gate {v, 0x20, "MC_writes_0"}, \ 2757c478bd9Sstevel@tonic-gate {v, 0x21, "MC_writes_1"}, \ 2767c478bd9Sstevel@tonic-gate {v, 0x22, "MC_writes_2"}, \ 2777c478bd9Sstevel@tonic-gate {v, 0x23, "MC_writes_3"}, \ 2787c478bd9Sstevel@tonic-gate {v, 0x24, "MC_stalls_1"}, \ 2797c478bd9Sstevel@tonic-gate {v, 0x25, "MC_stalls_3"} 2807c478bd9Sstevel@tonic-gate 2817c478bd9Sstevel@tonic-gate #define US3_I_MC_EVENTS_1(v) \ 2827c478bd9Sstevel@tonic-gate {v, 0x20, "MC_open_bank_cmds"}, \ 2837c478bd9Sstevel@tonic-gate {v, 0x21, "MC_reads"}, \ 2847c478bd9Sstevel@tonic-gate {v, 0x22, "MC_writes"}, \ 2857c478bd9Sstevel@tonic-gate {v, 0x23, "MC_page_close_stall"} 2867c478bd9Sstevel@tonic-gate 2877c478bd9Sstevel@tonic-gate static const struct nametable US3_names1[] = { 2887c478bd9Sstevel@tonic-gate USall_EVENTS_1(V_US3), 2897c478bd9Sstevel@tonic-gate US3all_EVENTS_1(V_US3), 2907c478bd9Sstevel@tonic-gate US3_MC_EVENTS_1(V_US3), 2917c478bd9Sstevel@tonic-gate {V_US3, 0x4, "Re_endian_miss"}, 2927c478bd9Sstevel@tonic-gate {V_END} 2937c478bd9Sstevel@tonic-gate }; 2947c478bd9Sstevel@tonic-gate 2957c478bd9Sstevel@tonic-gate static const struct nametable US3_PLUS_names1[] = { 2967c478bd9Sstevel@tonic-gate USall_EVENTS_1(V_US3_PLUS), 2977c478bd9Sstevel@tonic-gate US3all_EVENTS_1(V_US3_PLUS), 2987c478bd9Sstevel@tonic-gate US3_MC_EVENTS_1(V_US3_PLUS), 2997c478bd9Sstevel@tonic-gate {V_US3_PLUS, 0x4, "Re_DC_missovhd"}, 3007c478bd9Sstevel@tonic-gate {V_US3_PLUS, 0x28, "EC_miss_mtag_remote"}, 3017c478bd9Sstevel@tonic-gate {V_US3_PLUS, 0x29, "EC_miss_remote"}, 3027c478bd9Sstevel@tonic-gate {V_END} 3037c478bd9Sstevel@tonic-gate }; 3047c478bd9Sstevel@tonic-gate 3057c478bd9Sstevel@tonic-gate static const struct nametable US3_I_names1[] = { 3067c478bd9Sstevel@tonic-gate USall_EVENTS_1(V_US3_I), 3077c478bd9Sstevel@tonic-gate US3all_EVENTS_1(V_US3_I), 3087c478bd9Sstevel@tonic-gate US3_I_MC_EVENTS_1(V_US3_I), 3097c478bd9Sstevel@tonic-gate {V_US3_I, 0x4, "Re_DC_missovhd"}, 3107c478bd9Sstevel@tonic-gate {V_END} 3117c478bd9Sstevel@tonic-gate }; 312*23961e2bSvb70745 313*23961e2bSvb70745 static const struct nametable US4_PLUS_names1[] = { 314*23961e2bSvb70745 {V_US4_PLUS, 0x0, "Cycle_cnt"}, 315*23961e2bSvb70745 {V_US4_PLUS, 0x1, "Instr_cnt"}, 316*23961e2bSvb70745 {V_US4_PLUS, 0x2, "Dispatch0_other"}, 317*23961e2bSvb70745 {V_US4_PLUS, 0x3, "DC_wr"}, 318*23961e2bSvb70745 {V_US4_PLUS, 0x4, "Re_DC_missovhd"}, 319*23961e2bSvb70745 {V_US4_PLUS, 0x5, "Re_FPU_bypass"}, 320*23961e2bSvb70745 {V_US4_PLUS, 0x6, "L3_write_hit_RTO"}, 321*23961e2bSvb70745 {V_US4_PLUS, 0x7, "L2L3_snoop_inv_sh"}, 322*23961e2bSvb70745 {V_US4_PLUS, 0x8, "IC_L2_req"}, 323*23961e2bSvb70745 {V_US4_PLUS, 0x9, "DC_rd_miss"}, 324*23961e2bSvb70745 {V_US4_PLUS, 0xa, "L2_hit_I_state_sh"}, 325*23961e2bSvb70745 {V_US4_PLUS, 0xb, "L3_write_miss_RTO"}, 326*23961e2bSvb70745 {V_US4_PLUS, 0xc, "L2_miss"}, 327*23961e2bSvb70745 {V_US4_PLUS, 0xd, "SI_owned_sh"}, 328*23961e2bSvb70745 {V_US4_PLUS, 0xe, "SI_RTO_src_data"}, 329*23961e2bSvb70745 {V_US4_PLUS, 0xf, "SW_pf_duplicate"}, 330*23961e2bSvb70745 {V_US4_PLUS, 0x10, "IU_stat_jmp_mispred"}, 331*23961e2bSvb70745 {V_US4_PLUS, 0x11, "ITLB_miss"}, 332*23961e2bSvb70745 {V_US4_PLUS, 0x12, "DTLB_miss"}, 333*23961e2bSvb70745 {V_US4_PLUS, 0x13, "WC_miss"}, 334*23961e2bSvb70745 {V_US4_PLUS, 0x14, "IC_fill"}, 335*23961e2bSvb70745 {V_US4_PLUS, 0x15, "IU_stat_ret_mispred"}, 336*23961e2bSvb70745 {V_US4_PLUS, 0x16, "Re_L3_miss"}, 337*23961e2bSvb70745 {V_US4_PLUS, 0x17, "Re_PFQ_full"}, 338*23961e2bSvb70745 {V_US4_PLUS, 0x18, "PC_soft_hit"}, 339*23961e2bSvb70745 {V_US4_PLUS, 0x19, "PC_inv"}, 340*23961e2bSvb70745 {V_US4_PLUS, 0x1a, "PC_hard_hit"}, 341*23961e2bSvb70745 {V_US4_PLUS, 0x1b, "IC_pf"}, 342*23961e2bSvb70745 {V_US4_PLUS, 0x1c, "SW_count_NOP"}, 343*23961e2bSvb70745 {V_US4_PLUS, 0x1d, "IU_stat_br_miss_untaken"}, 344*23961e2bSvb70745 {V_US4_PLUS, 0x1e, "IU_stat_br_count_taken"}, 345*23961e2bSvb70745 {V_US4_PLUS, 0x1f, "PC_miss"}, 346*23961e2bSvb70745 {V_US4_PLUS, 0x20, "MC_writes_0_sh"}, 347*23961e2bSvb70745 {V_US4_PLUS, 0x21, "MC_writes_1_sh"}, 348*23961e2bSvb70745 {V_US4_PLUS, 0x22, "MC_writes_2_sh"}, 349*23961e2bSvb70745 {V_US4_PLUS, 0x23, "MC_writes_3_sh"}, 350*23961e2bSvb70745 {V_US4_PLUS, 0x24, "MC_stalls_1_sh"}, 351*23961e2bSvb70745 {V_US4_PLUS, 0x25, "MC_stalls_3_sh"}, 352*23961e2bSvb70745 {V_US4_PLUS, 0x26, "Re_RAW_miss"}, 353*23961e2bSvb70745 {V_US4_PLUS, 0x27, "FM_pipe_completion"}, 354*23961e2bSvb70745 {V_US4_PLUS, 0x28, "SSM_L3_miss_mtag_remote"}, 355*23961e2bSvb70745 {V_US4_PLUS, 0x29, "SSM_L3_miss_remote"}, 356*23961e2bSvb70745 {V_US4_PLUS, 0x2a, "SW_pf_exec"}, 357*23961e2bSvb70745 {V_US4_PLUS, 0x2b, "SW_pf_str_exec"}, 358*23961e2bSvb70745 {V_US4_PLUS, 0x2c, "SW_pf_dropped"}, 359*23961e2bSvb70745 {V_US4_PLUS, 0x2d, "SW_pf_L2_installed"}, 360*23961e2bSvb70745 {V_US4_PLUS, 0x2f, "L2_HW_pf_miss"}, 361*23961e2bSvb70745 {V_US4_PLUS, 0x31, "L3_miss"}, 362*23961e2bSvb70745 {V_US4_PLUS, 0x32, "L3_IC_miss"}, 363*23961e2bSvb70745 {V_US4_PLUS, 0x33, "L3_SW_pf_miss"}, 364*23961e2bSvb70745 {V_US4_PLUS, 0x34, "L3_hit_other_half"}, 365*23961e2bSvb70745 {V_US4_PLUS, 0x35, "L3_wb"}, 366*23961e2bSvb70745 {V_US4_PLUS, 0x36, "L3_wb_sh"}, 367*23961e2bSvb70745 {V_US4_PLUS, 0x37, "L2L3_snoop_cb_sh"}, 368*23961e2bSvb70745 {V_END} 369*23961e2bSvb70745 }; 370*23961e2bSvb70745 3717c478bd9Sstevel@tonic-gate #undef USall_EVENTS_1 3727c478bd9Sstevel@tonic-gate #undef US3all_EVENTS_1 3737c478bd9Sstevel@tonic-gate 3747c478bd9Sstevel@tonic-gate static const struct nametable *US12_names[2] = { 3757c478bd9Sstevel@tonic-gate US12_names0, 3767c478bd9Sstevel@tonic-gate US12_names1 3777c478bd9Sstevel@tonic-gate }; 3787c478bd9Sstevel@tonic-gate 3797c478bd9Sstevel@tonic-gate static const struct nametable *US3_names[2] = { 3807c478bd9Sstevel@tonic-gate US3_names0, 3817c478bd9Sstevel@tonic-gate US3_names1 3827c478bd9Sstevel@tonic-gate }; 3837c478bd9Sstevel@tonic-gate 3847c478bd9Sstevel@tonic-gate static const struct nametable *US3_PLUS_names[2] = { 3857c478bd9Sstevel@tonic-gate US3_PLUS_names0, 3867c478bd9Sstevel@tonic-gate US3_PLUS_names1 3877c478bd9Sstevel@tonic-gate }; 3887c478bd9Sstevel@tonic-gate 3897c478bd9Sstevel@tonic-gate static const struct nametable *US3_I_names[2] = { 3907c478bd9Sstevel@tonic-gate US3_I_names0, 3917c478bd9Sstevel@tonic-gate US3_I_names1 3927c478bd9Sstevel@tonic-gate }; 3937c478bd9Sstevel@tonic-gate 394*23961e2bSvb70745 static const struct nametable *US4_PLUS_names[2] = { 395*23961e2bSvb70745 US4_PLUS_names0, 396*23961e2bSvb70745 US4_PLUS_names1 397*23961e2bSvb70745 }; 398*23961e2bSvb70745 3997c478bd9Sstevel@tonic-gate #define MAPCPUVER(cpuver) (cpuvermap[(cpuver) - CPC_ULTRA1]) 4007c478bd9Sstevel@tonic-gate 4017c478bd9Sstevel@tonic-gate static int 4027c478bd9Sstevel@tonic-gate validargs(int cpuver, int regno) 4037c478bd9Sstevel@tonic-gate { 4047c478bd9Sstevel@tonic-gate if (regno < 0 || regno > 1) 4057c478bd9Sstevel@tonic-gate return (0); 4067c478bd9Sstevel@tonic-gate cpuver -= CPC_ULTRA1; 4077c478bd9Sstevel@tonic-gate if (cpuver < 0 || 4087c478bd9Sstevel@tonic-gate cpuver >= sizeof (cpuvermap) / sizeof (cpuvermap[0])) 4097c478bd9Sstevel@tonic-gate return (0); 4107c478bd9Sstevel@tonic-gate return (1); 4117c478bd9Sstevel@tonic-gate } 4127c478bd9Sstevel@tonic-gate 4137c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 4147c478bd9Sstevel@tonic-gate static int 4157c478bd9Sstevel@tonic-gate versionmatch(int cpuver, int regno, const struct nametable *n) 4167c478bd9Sstevel@tonic-gate { 4177c478bd9Sstevel@tonic-gate if (!validargs(cpuver, regno) || n->ver != MAPCPUVER(cpuver)) 4187c478bd9Sstevel@tonic-gate return (0); 4197c478bd9Sstevel@tonic-gate return (1); 4207c478bd9Sstevel@tonic-gate } 4217c478bd9Sstevel@tonic-gate 4227c478bd9Sstevel@tonic-gate static const struct nametable * 4237c478bd9Sstevel@tonic-gate getnametable(int cpuver, int regno) 4247c478bd9Sstevel@tonic-gate { 4257c478bd9Sstevel@tonic-gate const struct nametable *n; 4267c478bd9Sstevel@tonic-gate 4277c478bd9Sstevel@tonic-gate if (!validargs(cpuver, regno)) 4287c478bd9Sstevel@tonic-gate return (NULL); 4297c478bd9Sstevel@tonic-gate 4307c478bd9Sstevel@tonic-gate switch (MAPCPUVER(cpuver)) { 4317c478bd9Sstevel@tonic-gate case V_US12: 4327c478bd9Sstevel@tonic-gate n = US12_names[regno]; 4337c478bd9Sstevel@tonic-gate break; 4347c478bd9Sstevel@tonic-gate case V_US3: 4357c478bd9Sstevel@tonic-gate n = US3_names[regno]; 4367c478bd9Sstevel@tonic-gate break; 4377c478bd9Sstevel@tonic-gate case V_US3_PLUS: 4387c478bd9Sstevel@tonic-gate n = US3_PLUS_names[regno]; 4397c478bd9Sstevel@tonic-gate break; 4407c478bd9Sstevel@tonic-gate case V_US3_I: 4417c478bd9Sstevel@tonic-gate n = US3_I_names[regno]; 4427c478bd9Sstevel@tonic-gate break; 443*23961e2bSvb70745 case V_US4_PLUS: 444*23961e2bSvb70745 n = US4_PLUS_names[regno]; 445*23961e2bSvb70745 break; 4467c478bd9Sstevel@tonic-gate default: 4477c478bd9Sstevel@tonic-gate n = NULL; 4487c478bd9Sstevel@tonic-gate break; 4497c478bd9Sstevel@tonic-gate } 4507c478bd9Sstevel@tonic-gate return (n); 4517c478bd9Sstevel@tonic-gate } 4527c478bd9Sstevel@tonic-gate 4537c478bd9Sstevel@tonic-gate void 4547c478bd9Sstevel@tonic-gate cpc_walk_names(int cpuver, int regno, void *arg, 4557c478bd9Sstevel@tonic-gate void (*action)(void *, int, const char *, uint8_t)) 4567c478bd9Sstevel@tonic-gate { 4577c478bd9Sstevel@tonic-gate const struct nametable *n; 4587c478bd9Sstevel@tonic-gate 4597c478bd9Sstevel@tonic-gate if ((n = getnametable(cpuver, regno)) == NULL) 4607c478bd9Sstevel@tonic-gate return; 4617c478bd9Sstevel@tonic-gate for (; n->ver != V_END; n++) 4627c478bd9Sstevel@tonic-gate if (versionmatch(cpuver, regno, n)) 4637c478bd9Sstevel@tonic-gate action(arg, regno, n->name, n->bits); 4647c478bd9Sstevel@tonic-gate } 4657c478bd9Sstevel@tonic-gate 4667c478bd9Sstevel@tonic-gate const char * 4677c478bd9Sstevel@tonic-gate __cpc_reg_to_name(int cpuver, int regno, uint8_t bits) 4687c478bd9Sstevel@tonic-gate { 4697c478bd9Sstevel@tonic-gate const struct nametable *n; 4707c478bd9Sstevel@tonic-gate 4717c478bd9Sstevel@tonic-gate if ((n = getnametable(cpuver, regno)) == NULL) 4727c478bd9Sstevel@tonic-gate return (NULL); 4737c478bd9Sstevel@tonic-gate for (; n->ver != V_END; n++) 4747c478bd9Sstevel@tonic-gate if (bits == n->bits && versionmatch(cpuver, regno, n)) 4757c478bd9Sstevel@tonic-gate return (n->name); 4767c478bd9Sstevel@tonic-gate return (NULL); 4777c478bd9Sstevel@tonic-gate } 4787c478bd9Sstevel@tonic-gate 4797c478bd9Sstevel@tonic-gate /* 4807c478bd9Sstevel@tonic-gate * Register names can be specified as strings or even as numbers 4817c478bd9Sstevel@tonic-gate */ 4827c478bd9Sstevel@tonic-gate int 4837c478bd9Sstevel@tonic-gate __cpc_name_to_reg(int cpuver, int regno, const char *name, uint8_t *bits) 4847c478bd9Sstevel@tonic-gate { 4857c478bd9Sstevel@tonic-gate const struct nametable *n; 4867c478bd9Sstevel@tonic-gate char *eptr = NULL; 4877c478bd9Sstevel@tonic-gate long value; 4887c478bd9Sstevel@tonic-gate 4897c478bd9Sstevel@tonic-gate if ((n = getnametable(cpuver, regno)) == NULL || name == NULL) 4907c478bd9Sstevel@tonic-gate return (-1); 4917c478bd9Sstevel@tonic-gate 4927c478bd9Sstevel@tonic-gate for (; n->ver != V_END; n++) 4937c478bd9Sstevel@tonic-gate if (strcmp(name, n->name) == 0 && 4947c478bd9Sstevel@tonic-gate versionmatch(cpuver, regno, n)) { 4957c478bd9Sstevel@tonic-gate *bits = n->bits; 4967c478bd9Sstevel@tonic-gate return (0); 4977c478bd9Sstevel@tonic-gate } 4987c478bd9Sstevel@tonic-gate 4997c478bd9Sstevel@tonic-gate value = strtol(name, &eptr, 0); 5007c478bd9Sstevel@tonic-gate if (name != eptr && value >= 0 && value <= UINT8_MAX) { 5017c478bd9Sstevel@tonic-gate *bits = (uint8_t)value; 5027c478bd9Sstevel@tonic-gate return (0); 5037c478bd9Sstevel@tonic-gate } 5047c478bd9Sstevel@tonic-gate 5057c478bd9Sstevel@tonic-gate return (-1); 5067c478bd9Sstevel@tonic-gate } 5077c478bd9Sstevel@tonic-gate 5087c478bd9Sstevel@tonic-gate const char * 5097c478bd9Sstevel@tonic-gate cpc_getcciname(int cpuver) 5107c478bd9Sstevel@tonic-gate { 5117c478bd9Sstevel@tonic-gate if (validargs(cpuver, 0)) 5127c478bd9Sstevel@tonic-gate switch (MAPCPUVER(cpuver)) { 5137c478bd9Sstevel@tonic-gate case V_US12: 5147c478bd9Sstevel@tonic-gate return ("UltraSPARC I&II"); 5157c478bd9Sstevel@tonic-gate case V_US3: 5167c478bd9Sstevel@tonic-gate return ("UltraSPARC III"); 5177c478bd9Sstevel@tonic-gate case V_US3_PLUS: 5187c478bd9Sstevel@tonic-gate return ("UltraSPARC III+ & IV"); 5197c478bd9Sstevel@tonic-gate case V_US3_I: 5207c478bd9Sstevel@tonic-gate return ("UltraSPARC IIIi & IIIi+"); 521*23961e2bSvb70745 case V_US4_PLUS: 522*23961e2bSvb70745 return ("UltraSPARC IV+"); 5237c478bd9Sstevel@tonic-gate default: 5247c478bd9Sstevel@tonic-gate break; 5257c478bd9Sstevel@tonic-gate } 5267c478bd9Sstevel@tonic-gate return (NULL); 5277c478bd9Sstevel@tonic-gate } 5287c478bd9Sstevel@tonic-gate 5297c478bd9Sstevel@tonic-gate #define CPU_REF_URL " Documentation for Sun processors can be found at: " \ 5307c478bd9Sstevel@tonic-gate "http://www.sun.com/processors/manuals" 5317c478bd9Sstevel@tonic-gate 5327c478bd9Sstevel@tonic-gate const char * 5337c478bd9Sstevel@tonic-gate cpc_getcpuref(int cpuver) 5347c478bd9Sstevel@tonic-gate { 5357c478bd9Sstevel@tonic-gate if (validargs(cpuver, 0)) 5367c478bd9Sstevel@tonic-gate switch (MAPCPUVER(cpuver)) { 5377c478bd9Sstevel@tonic-gate case V_US12: 5387c478bd9Sstevel@tonic-gate return (gettext( 5397c478bd9Sstevel@tonic-gate "See the \"UltraSPARC I/II User\'s Manual\" " 5407c478bd9Sstevel@tonic-gate "(Part No. 802-7220-02) " 5417c478bd9Sstevel@tonic-gate "for descriptions of these events." CPU_REF_URL)); 5427c478bd9Sstevel@tonic-gate case V_US3: 5437c478bd9Sstevel@tonic-gate case V_US3_PLUS: 5447c478bd9Sstevel@tonic-gate return (gettext( 5457c478bd9Sstevel@tonic-gate "See the \"UltraSPARC III Cu User's Manual\" " 5467c478bd9Sstevel@tonic-gate "for descriptions of these events." CPU_REF_URL)); 5477c478bd9Sstevel@tonic-gate case V_US3_I: 5487c478bd9Sstevel@tonic-gate return (gettext( 5497c478bd9Sstevel@tonic-gate "See the \"UltraSPARC IIIi User's Manual\" " 5507c478bd9Sstevel@tonic-gate "for descriptions of these events." CPU_REF_URL)); 551*23961e2bSvb70745 case V_US4_PLUS: 552*23961e2bSvb70745 return (gettext( 553*23961e2bSvb70745 "See the \"UltraSPARC IV User's Manual" 554*23961e2bSvb70745 "Supplement\" " 555*23961e2bSvb70745 "for descriptions of these events." CPU_REF_URL)); 5567c478bd9Sstevel@tonic-gate default: 5577c478bd9Sstevel@tonic-gate break; 5587c478bd9Sstevel@tonic-gate } 5597c478bd9Sstevel@tonic-gate return (NULL); 5607c478bd9Sstevel@tonic-gate } 5617c478bd9Sstevel@tonic-gate 5627c478bd9Sstevel@tonic-gate /* 5637c478bd9Sstevel@tonic-gate * This is a functional interface to allow CPUs with fewer %pic registers 5647c478bd9Sstevel@tonic-gate * to share the same data structure as those with more %pic registers 5657c478bd9Sstevel@tonic-gate * within the same instruction family. 5667c478bd9Sstevel@tonic-gate */ 5677c478bd9Sstevel@tonic-gate uint_t 5687c478bd9Sstevel@tonic-gate cpc_getnpic(int cpuver) 5697c478bd9Sstevel@tonic-gate { 5707c478bd9Sstevel@tonic-gate /*LINTED*/ 5717c478bd9Sstevel@tonic-gate cpc_event_t *event; 5727c478bd9Sstevel@tonic-gate 5737c478bd9Sstevel@tonic-gate switch (cpuver) { 5747c478bd9Sstevel@tonic-gate case CPC_ULTRA1: 5757c478bd9Sstevel@tonic-gate case CPC_ULTRA2: 5767c478bd9Sstevel@tonic-gate case CPC_ULTRA3: 5777c478bd9Sstevel@tonic-gate case CPC_ULTRA3_PLUS: 5787c478bd9Sstevel@tonic-gate case CPC_ULTRA3_I: 579*23961e2bSvb70745 case CPC_ULTRA4_PLUS: 5807c478bd9Sstevel@tonic-gate return (sizeof (event->ce_pic) / sizeof (event->ce_pic[0])); 5817c478bd9Sstevel@tonic-gate default: 5827c478bd9Sstevel@tonic-gate return (0); 5837c478bd9Sstevel@tonic-gate } 5847c478bd9Sstevel@tonic-gate } 5857c478bd9Sstevel@tonic-gate 5867c478bd9Sstevel@tonic-gate /* 5877c478bd9Sstevel@tonic-gate * Compares the given string against the list of all known CPU node names, and 5887c478bd9Sstevel@tonic-gate * returns the CPC CPU version code if there is a match. If there is no match, 5897c478bd9Sstevel@tonic-gate * returns -1. 5907c478bd9Sstevel@tonic-gate */ 5917c478bd9Sstevel@tonic-gate static int 5927c478bd9Sstevel@tonic-gate node2ver(char *node) 5937c478bd9Sstevel@tonic-gate { 5947c478bd9Sstevel@tonic-gate if (strcmp(node, "SUNW,UltraSPARC") == 0 || 5957c478bd9Sstevel@tonic-gate strcmp(node, "SUNW,UltraSPARC-II") == 0 || 5967c478bd9Sstevel@tonic-gate strcmp(node, "SUNW,UltraSPARC-IIi") == 0 || 5977c478bd9Sstevel@tonic-gate strcmp(node, "SUNW,UltraSPARC-IIe") == 0) { 5987c478bd9Sstevel@tonic-gate return (CPC_ULTRA1); 5997c478bd9Sstevel@tonic-gate } else if (strcmp(node, "SUNW,UltraSPARC-III") == 0) 6007c478bd9Sstevel@tonic-gate return (CPC_ULTRA3); 6017c478bd9Sstevel@tonic-gate else if (strcmp(node, "SUNW,UltraSPARC-III+") == 0 || 602*23961e2bSvb70745 strcmp(node, "SUNW,UltraSPARC-IV") == 0) 6037c478bd9Sstevel@tonic-gate return (CPC_ULTRA3_PLUS); 6047c478bd9Sstevel@tonic-gate else if (strcmp(node, "SUNW,UltraSPARC-IIIi") == 0 || 6057c478bd9Sstevel@tonic-gate strcmp(node, "SUNW,UltraSPARC-IIIi+") == 0) 6067c478bd9Sstevel@tonic-gate return (CPC_ULTRA3_I); 607*23961e2bSvb70745 else if (strcmp(node, "SUNW,UltraSPARC-IV+") == 0) 608*23961e2bSvb70745 return (CPC_ULTRA4_PLUS); 6097c478bd9Sstevel@tonic-gate 6107c478bd9Sstevel@tonic-gate return (-1); 6117c478bd9Sstevel@tonic-gate } 6127c478bd9Sstevel@tonic-gate 6137c478bd9Sstevel@tonic-gate static int 6147c478bd9Sstevel@tonic-gate cpc_get_cpu_ver(di_node_t di_node, void *arg) 6157c478bd9Sstevel@tonic-gate { 6167c478bd9Sstevel@tonic-gate char *node_name, *compatible_array; 6177c478bd9Sstevel@tonic-gate int n_names, i, found = 0; 6187c478bd9Sstevel@tonic-gate int *ver = arg; 6197c478bd9Sstevel@tonic-gate 6207c478bd9Sstevel@tonic-gate node_name = di_node_name(di_node); 6217c478bd9Sstevel@tonic-gate if (node_name != NULL) { 6227c478bd9Sstevel@tonic-gate if ((*ver = node2ver(node_name)) != -1) 6237c478bd9Sstevel@tonic-gate found = 1; 6247c478bd9Sstevel@tonic-gate else if (strncmp(node_name, "cpu", 4) == 0) { 6257c478bd9Sstevel@tonic-gate /* 6267c478bd9Sstevel@tonic-gate * CPU nodes associated with CMP use the generic name 6277c478bd9Sstevel@tonic-gate * of "cpu". We must look at the compatible property 6287c478bd9Sstevel@tonic-gate * in order to find the implementation specific name. 6297c478bd9Sstevel@tonic-gate */ 6307c478bd9Sstevel@tonic-gate if ((n_names = di_compatible_names(di_node, 6317c478bd9Sstevel@tonic-gate &compatible_array)) > 0) { 6327c478bd9Sstevel@tonic-gate for (i = 0; i < n_names; i++) { 6337c478bd9Sstevel@tonic-gate if ((*ver = node2ver(compatible_array)) 6347c478bd9Sstevel@tonic-gate != -1) { 6357c478bd9Sstevel@tonic-gate found = 1; 6367c478bd9Sstevel@tonic-gate break; 6377c478bd9Sstevel@tonic-gate } 6387c478bd9Sstevel@tonic-gate compatible_array += 6397c478bd9Sstevel@tonic-gate strlen(compatible_array) + 1; 6407c478bd9Sstevel@tonic-gate } 6417c478bd9Sstevel@tonic-gate } 6427c478bd9Sstevel@tonic-gate } 6437c478bd9Sstevel@tonic-gate } 6447c478bd9Sstevel@tonic-gate 6457c478bd9Sstevel@tonic-gate if (found == 0) 6467c478bd9Sstevel@tonic-gate return (DI_WALK_CONTINUE); 6477c478bd9Sstevel@tonic-gate 6487c478bd9Sstevel@tonic-gate return (DI_WALK_TERMINATE); 6497c478bd9Sstevel@tonic-gate } 6507c478bd9Sstevel@tonic-gate 6517c478bd9Sstevel@tonic-gate /* 6527c478bd9Sstevel@tonic-gate * Return the version of the current processor. 6537c478bd9Sstevel@tonic-gate * 6547c478bd9Sstevel@tonic-gate * Version -1 is defined as 'not performance counter capable' 6557c478bd9Sstevel@tonic-gate * 6567c478bd9Sstevel@tonic-gate * XXX A better solution would be to use the di_prom_props for the cpu 6577c478bd9Sstevel@tonic-gate * devinfo nodes. That way we could look at the 'device-type', 'sparc-version' 6587c478bd9Sstevel@tonic-gate * and 'implementation#' properties in order to determine which version of 6597c478bd9Sstevel@tonic-gate * UltraSPARC we are running on. 6607c478bd9Sstevel@tonic-gate * 6617c478bd9Sstevel@tonic-gate * The problem with this is that di_prom_init() requires root access to 6627c478bd9Sstevel@tonic-gate * open /dev/openprom and cputrack is not a root-only application so 6637c478bd9Sstevel@tonic-gate * we have to settle for the di_props that we can see as non-root users. 6647c478bd9Sstevel@tonic-gate */ 6657c478bd9Sstevel@tonic-gate int 6667c478bd9Sstevel@tonic-gate cpc_getcpuver(void) 6677c478bd9Sstevel@tonic-gate { 6687c478bd9Sstevel@tonic-gate static int ver = -1; 6697c478bd9Sstevel@tonic-gate 6707c478bd9Sstevel@tonic-gate if (ver == -1) { 6717c478bd9Sstevel@tonic-gate di_node_t di_root_node; 6727c478bd9Sstevel@tonic-gate 6737c478bd9Sstevel@tonic-gate if ((di_root_node = di_init("/", DINFOCPYALL)) == DI_NODE_NIL) 6747c478bd9Sstevel@tonic-gate return (-1); 6757c478bd9Sstevel@tonic-gate 6767c478bd9Sstevel@tonic-gate (void) di_walk_node(di_root_node, DI_WALK_CLDFIRST, 6777c478bd9Sstevel@tonic-gate (void *)&ver, cpc_get_cpu_ver); 6787c478bd9Sstevel@tonic-gate 6797c478bd9Sstevel@tonic-gate di_fini(di_root_node); 6807c478bd9Sstevel@tonic-gate } 6817c478bd9Sstevel@tonic-gate return (ver); 6827c478bd9Sstevel@tonic-gate } 683