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