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
validargs(int cpuver,int regno)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
versionmatch(int cpuver,int regno,const struct nametable * n)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 *
getnametable(int cpuver,int regno)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
cpc_walk_names(int cpuver,int regno,void * arg,void (* action)(void *,int,const char *,uint8_t))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 *
__cpc_reg_to_name(int cpuver,int regno,uint8_t bits)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
__cpc_name_to_reg(int cpuver,int regno,const char * name,uint8_t * bits)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 *
cpc_getcciname(int cpuver)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 *
cpc_getcpuref(int cpuver)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
cpc_getnpic(int cpuver)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
node2ver(char * node)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
cpc_get_cpu_ver(di_node_t di_node,void * arg)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
cpc_getcpuver(void)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