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 5820c9f58Skk208521 * Common Development and Distribution License (the "License"). 6820c9f58Skk208521 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22820c9f58Skk208521 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate /* 27*c7a079a8SJonathan Haslam * This file contains preset event names from the Performance Application 28*c7a079a8SJonathan Haslam * Programming Interface v3.5 which included the following notice: 29*c7a079a8SJonathan Haslam * 30*c7a079a8SJonathan Haslam * Copyright (c) 2005,6 31*c7a079a8SJonathan Haslam * Innovative Computing Labs 32*c7a079a8SJonathan Haslam * Computer Science Department, 33*c7a079a8SJonathan Haslam * University of Tennessee, 34*c7a079a8SJonathan Haslam * Knoxville, TN. 35*c7a079a8SJonathan Haslam * All Rights Reserved. 36*c7a079a8SJonathan Haslam * 37*c7a079a8SJonathan Haslam * 38*c7a079a8SJonathan Haslam * Redistribution and use in source and binary forms, with or without 39*c7a079a8SJonathan Haslam * modification, are permitted provided that the following conditions are met: 40*c7a079a8SJonathan Haslam * 41*c7a079a8SJonathan Haslam * * Redistributions of source code must retain the above copyright notice, 42*c7a079a8SJonathan Haslam * this list of conditions and the following disclaimer. 43*c7a079a8SJonathan Haslam * * Redistributions in binary form must reproduce the above copyright 44*c7a079a8SJonathan Haslam * notice, this list of conditions and the following disclaimer in the 45*c7a079a8SJonathan Haslam * documentation and/or other materials provided with the distribution. 46*c7a079a8SJonathan Haslam * * Neither the name of the University of Tennessee nor the names of its 47*c7a079a8SJonathan Haslam * contributors may be used to endorse or promote products derived from 48*c7a079a8SJonathan Haslam * this software without specific prior written permission. 49*c7a079a8SJonathan Haslam * 50*c7a079a8SJonathan Haslam * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 51*c7a079a8SJonathan Haslam * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 52*c7a079a8SJonathan Haslam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 53*c7a079a8SJonathan Haslam * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 54*c7a079a8SJonathan Haslam * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 55*c7a079a8SJonathan Haslam * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 56*c7a079a8SJonathan Haslam * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 57*c7a079a8SJonathan Haslam * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 58*c7a079a8SJonathan Haslam * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 59*c7a079a8SJonathan Haslam * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 60*c7a079a8SJonathan Haslam * POSSIBILITY OF SUCH DAMAGE. 61*c7a079a8SJonathan Haslam * 62*c7a079a8SJonathan Haslam * 63*c7a079a8SJonathan Haslam * This open source software license conforms to the BSD License template. 647c478bd9Sstevel@tonic-gate */ 657c478bd9Sstevel@tonic-gate 66*c7a079a8SJonathan Haslam /* 67*c7a079a8SJonathan Haslam * UltraSPARC Performance Counter Backend 68*c7a079a8SJonathan Haslam */ 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate #include <sys/cpuvar.h> 717c478bd9Sstevel@tonic-gate #include <sys/systm.h> 727c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h> 737c478bd9Sstevel@tonic-gate #include <sys/spitregs.h> 747c478bd9Sstevel@tonic-gate #include <sys/cheetahregs.h> 757c478bd9Sstevel@tonic-gate #include <sys/cpc_impl.h> 767c478bd9Sstevel@tonic-gate #include <sys/cpc_pcbe.h> 777c478bd9Sstevel@tonic-gate #include <sys/modctl.h> 787c478bd9Sstevel@tonic-gate #include <sys/machsystm.h> 797c478bd9Sstevel@tonic-gate #include <sys/sdt.h> 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate static int us_pcbe_init(void); 827c478bd9Sstevel@tonic-gate static uint_t us_pcbe_ncounters(void); 837c478bd9Sstevel@tonic-gate static const char *us_pcbe_impl_name(void); 847c478bd9Sstevel@tonic-gate static const char *us_pcbe_cpuref(void); 857c478bd9Sstevel@tonic-gate static char *us_pcbe_list_events(uint_t picnum); 867c478bd9Sstevel@tonic-gate static char *us_pcbe_list_attrs(void); 877c478bd9Sstevel@tonic-gate static uint64_t us_pcbe_event_coverage(char *event); 887c478bd9Sstevel@tonic-gate static uint64_t us_pcbe_overflow_bitmap(void); 897c478bd9Sstevel@tonic-gate static int us_pcbe_configure(uint_t picnum, char *event, uint64_t preset, 907c478bd9Sstevel@tonic-gate uint32_t flags, uint_t nattrs, kcpc_attr_t *attrs, void **data, 917c478bd9Sstevel@tonic-gate void *token); 927c478bd9Sstevel@tonic-gate static void us_pcbe_program(void *token); 937c478bd9Sstevel@tonic-gate static void us_pcbe_allstop(void); 947c478bd9Sstevel@tonic-gate static void us_pcbe_sample(void *token); 957c478bd9Sstevel@tonic-gate static void us_pcbe_free(void *config); 967c478bd9Sstevel@tonic-gate 977c478bd9Sstevel@tonic-gate extern void ultra_setpcr(uint64_t); 987c478bd9Sstevel@tonic-gate extern uint64_t ultra_getpcr(void); 997c478bd9Sstevel@tonic-gate extern void ultra_setpic(uint64_t); 1007c478bd9Sstevel@tonic-gate extern uint64_t ultra_getpic(void); 1017c478bd9Sstevel@tonic-gate extern uint64_t ultra_gettick(void); 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate pcbe_ops_t us_pcbe_ops = { 1047c478bd9Sstevel@tonic-gate PCBE_VER_1, 1057c478bd9Sstevel@tonic-gate CPC_CAP_OVERFLOW_INTERRUPT, 1067c478bd9Sstevel@tonic-gate us_pcbe_ncounters, 1077c478bd9Sstevel@tonic-gate us_pcbe_impl_name, 1087c478bd9Sstevel@tonic-gate us_pcbe_cpuref, 1097c478bd9Sstevel@tonic-gate us_pcbe_list_events, 1107c478bd9Sstevel@tonic-gate us_pcbe_list_attrs, 1117c478bd9Sstevel@tonic-gate us_pcbe_event_coverage, 1127c478bd9Sstevel@tonic-gate us_pcbe_overflow_bitmap, 1137c478bd9Sstevel@tonic-gate us_pcbe_configure, 1147c478bd9Sstevel@tonic-gate us_pcbe_program, 1157c478bd9Sstevel@tonic-gate us_pcbe_allstop, 1167c478bd9Sstevel@tonic-gate us_pcbe_sample, 1177c478bd9Sstevel@tonic-gate us_pcbe_free 1187c478bd9Sstevel@tonic-gate }; 1197c478bd9Sstevel@tonic-gate 1207c478bd9Sstevel@tonic-gate typedef struct _us_pcbe_config { 1217c478bd9Sstevel@tonic-gate uint8_t us_picno; /* 0 for pic0 or 1 for pic1 */ 1227c478bd9Sstevel@tonic-gate uint32_t us_bits; /* %pcr event code unshifted */ 1237c478bd9Sstevel@tonic-gate uint32_t us_flags; /* user/system/priv */ 1247c478bd9Sstevel@tonic-gate uint32_t us_pic; /* unshifted raw %pic value */ 1257c478bd9Sstevel@tonic-gate } us_pcbe_config_t; 1267c478bd9Sstevel@tonic-gate 1277c478bd9Sstevel@tonic-gate struct nametable { 1287c478bd9Sstevel@tonic-gate const uint8_t bits; 1297c478bd9Sstevel@tonic-gate const char *name; 1307c478bd9Sstevel@tonic-gate }; 1317c478bd9Sstevel@tonic-gate 132*c7a079a8SJonathan Haslam typedef struct _us_generic_event { 133*c7a079a8SJonathan Haslam char *name; 134*c7a079a8SJonathan Haslam char *event; 135*c7a079a8SJonathan Haslam } us_generic_event_t; 136*c7a079a8SJonathan Haslam 1377c478bd9Sstevel@tonic-gate #define PIC0_MASK (((uint64_t)1 << 32) - 1) 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate #define ULTRA_PCR_SYS (UINT64_C(1) << CPC_ULTRA_PCR_SYS) 1407c478bd9Sstevel@tonic-gate #define ULTRA_PCR_PRIVPIC (UINT64_C(1) << CPC_ULTRA_PCR_PRIVPIC) 1417c478bd9Sstevel@tonic-gate 1427c478bd9Sstevel@tonic-gate #define CPC_ULTRA_PCR_USR 2 1437c478bd9Sstevel@tonic-gate #define CPC_ULTRA_PCR_SYS 1 1447c478bd9Sstevel@tonic-gate #define CPC_ULTRA_PCR_PRIVPIC 0 1457c478bd9Sstevel@tonic-gate 1467c478bd9Sstevel@tonic-gate #define CPC_ULTRA_PCR_PIC0_SHIFT 4 1477c478bd9Sstevel@tonic-gate #define CPC_ULTRA2_PCR_PIC_MASK UINT64_C(0xf) 1487c478bd9Sstevel@tonic-gate #define CPC_ULTRA3_PCR_PIC_MASK UINT64_C(0x3f) 1497c478bd9Sstevel@tonic-gate #define CPC_ULTRA_PCR_PIC1_SHIFT 11 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate #define NT_END 0xFF 152*c7a079a8SJonathan Haslam #define CPC_GEN_END { NULL, NULL } 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate static const uint64_t allstopped = ULTRA_PCR_PRIVPIC; 1557c478bd9Sstevel@tonic-gate 1567c478bd9Sstevel@tonic-gate #define USall_EVENTS_0 \ 1577c478bd9Sstevel@tonic-gate {0x0, "Cycle_cnt"}, \ 1587c478bd9Sstevel@tonic-gate {0x1, "Instr_cnt"}, \ 1597c478bd9Sstevel@tonic-gate {0x2, "Dispatch0_IC_miss"}, \ 1607c478bd9Sstevel@tonic-gate {0x8, "IC_ref"}, \ 1617c478bd9Sstevel@tonic-gate {0x9, "DC_rd"}, \ 1627c478bd9Sstevel@tonic-gate {0xa, "DC_wr"}, \ 1637c478bd9Sstevel@tonic-gate {0xc, "EC_ref"}, \ 1647c478bd9Sstevel@tonic-gate {0xe, "EC_snoop_inv"} 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate static const struct nametable US12_names0[] = { 1677c478bd9Sstevel@tonic-gate USall_EVENTS_0, 1687c478bd9Sstevel@tonic-gate {0x3, "Dispatch0_storeBuf"}, 1697c478bd9Sstevel@tonic-gate {0xb, "Load_use"}, 1707c478bd9Sstevel@tonic-gate {0xd, "EC_write_hit_RDO"}, 1717c478bd9Sstevel@tonic-gate {0xf, "EC_rd_hit"}, 1727c478bd9Sstevel@tonic-gate {NT_END, ""} 1737c478bd9Sstevel@tonic-gate }; 1747c478bd9Sstevel@tonic-gate 1757c478bd9Sstevel@tonic-gate #define US3all_EVENTS_0 \ 1767c478bd9Sstevel@tonic-gate {0x3, "Dispatch0_br_target"}, \ 1777c478bd9Sstevel@tonic-gate {0x4, "Dispatch0_2nd_br"}, \ 1787c478bd9Sstevel@tonic-gate {0x5, "Rstall_storeQ"}, \ 1797c478bd9Sstevel@tonic-gate {0x6, "Rstall_IU_use"}, \ 1807c478bd9Sstevel@tonic-gate {0xd, "EC_write_hit_RTO"}, \ 1817c478bd9Sstevel@tonic-gate {0xf, "EC_rd_miss"}, \ 1827c478bd9Sstevel@tonic-gate {0x10, "PC_port0_rd"}, \ 1837c478bd9Sstevel@tonic-gate {0x11, "SI_snoop"}, \ 1847c478bd9Sstevel@tonic-gate {0x12, "SI_ciq_flow"}, \ 1857c478bd9Sstevel@tonic-gate {0x13, "SI_owned"}, \ 1867c478bd9Sstevel@tonic-gate {0x14, "SW_count_0"}, \ 1877c478bd9Sstevel@tonic-gate {0x15, "IU_Stat_Br_miss_taken"}, \ 1887c478bd9Sstevel@tonic-gate {0x16, "IU_Stat_Br_count_taken"}, \ 1897c478bd9Sstevel@tonic-gate {0x17, "Dispatch_rs_mispred"}, \ 1907c478bd9Sstevel@tonic-gate {0x18, "FA_pipe_completion"} 1917c478bd9Sstevel@tonic-gate 1927c478bd9Sstevel@tonic-gate #define US3_MC_EVENTS_0 \ 1937c478bd9Sstevel@tonic-gate {0x20, "MC_reads_0"}, \ 1947c478bd9Sstevel@tonic-gate {0x21, "MC_reads_1"}, \ 1957c478bd9Sstevel@tonic-gate {0x22, "MC_reads_2"}, \ 1967c478bd9Sstevel@tonic-gate {0x23, "MC_reads_3"}, \ 1977c478bd9Sstevel@tonic-gate {0x24, "MC_stalls_0"}, \ 1987c478bd9Sstevel@tonic-gate {0x25, "MC_stalls_2"} 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate #define US3_I_MC_EVENTS_0 \ 2017c478bd9Sstevel@tonic-gate {0x20, "MC_read_dispatched"}, \ 2027c478bd9Sstevel@tonic-gate {0x21, "MC_write_dispatched"}, \ 2037c478bd9Sstevel@tonic-gate {0x22, "MC_read_returned_to_JBU"}, \ 2047c478bd9Sstevel@tonic-gate {0x23, "MC_msl_busy_stall"}, \ 2057c478bd9Sstevel@tonic-gate {0x24, "MC_mdb_overflow_stall"}, \ 2067c478bd9Sstevel@tonic-gate {0x25, "MC_miu_spec_request"} 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate #define USall_EVENTS_1 \ 2097c478bd9Sstevel@tonic-gate {0x0, "Cycle_cnt"}, \ 2107c478bd9Sstevel@tonic-gate {0x1, "Instr_cnt"}, \ 2117c478bd9Sstevel@tonic-gate {0x2, "Dispatch0_mispred"}, \ 2127c478bd9Sstevel@tonic-gate {0xd, "EC_wb"}, \ 2137c478bd9Sstevel@tonic-gate {0xe, "EC_snoop_cb"} 2147c478bd9Sstevel@tonic-gate 2157c478bd9Sstevel@tonic-gate static const struct nametable US3_names0[] = { 2167c478bd9Sstevel@tonic-gate USall_EVENTS_0, 2177c478bd9Sstevel@tonic-gate US3all_EVENTS_0, 2187c478bd9Sstevel@tonic-gate US3_MC_EVENTS_0, 2197c478bd9Sstevel@tonic-gate {NT_END, ""} 2207c478bd9Sstevel@tonic-gate }; 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate static const struct nametable US3_PLUS_names0[] = { 2237c478bd9Sstevel@tonic-gate USall_EVENTS_0, 2247c478bd9Sstevel@tonic-gate US3all_EVENTS_0, 2257c478bd9Sstevel@tonic-gate US3_MC_EVENTS_0, 2267c478bd9Sstevel@tonic-gate {0x19, "EC_wb_remote"}, 2277c478bd9Sstevel@tonic-gate {0x1a, "EC_miss_local"}, 2287c478bd9Sstevel@tonic-gate {0x1b, "EC_miss_mtag_remote"}, 2297c478bd9Sstevel@tonic-gate {NT_END, ""} 2307c478bd9Sstevel@tonic-gate }; 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate static const struct nametable US3_I_names0[] = { 2337c478bd9Sstevel@tonic-gate USall_EVENTS_0, 2347c478bd9Sstevel@tonic-gate US3all_EVENTS_0, 2357c478bd9Sstevel@tonic-gate US3_I_MC_EVENTS_0, 2367c478bd9Sstevel@tonic-gate {NT_END, ""} 2377c478bd9Sstevel@tonic-gate }; 2387c478bd9Sstevel@tonic-gate 2397c478bd9Sstevel@tonic-gate static const struct nametable US4_PLUS_names0[] = { 2407c478bd9Sstevel@tonic-gate {0x0, "Cycle_cnt"}, 2417c478bd9Sstevel@tonic-gate {0x1, "Instr_cnt"}, 2427c478bd9Sstevel@tonic-gate {0x2, "Dispatch0_IC_miss"}, 2437c478bd9Sstevel@tonic-gate {0x3, "IU_stat_jmp_correct_pred"}, 2447c478bd9Sstevel@tonic-gate {0x4, "Dispatch0_2nd_br"}, 2457c478bd9Sstevel@tonic-gate {0x5, "Rstall_storeQ"}, 2467c478bd9Sstevel@tonic-gate {0x6, "Rstall_IU_use"}, 2477c478bd9Sstevel@tonic-gate {0x7, "IU_stat_ret_correct_pred"}, 2487c478bd9Sstevel@tonic-gate {0x8, "IC_ref"}, 2497c478bd9Sstevel@tonic-gate {0x9, "DC_rd"}, 2507c478bd9Sstevel@tonic-gate {0xa, "Rstall_FP_use"}, 2517c478bd9Sstevel@tonic-gate {0xb, "SW_pf_instr"}, 2527c478bd9Sstevel@tonic-gate {0xc, "L2_ref"}, 2537c478bd9Sstevel@tonic-gate {0xd, "L2_write_hit_RTO"}, 2547c478bd9Sstevel@tonic-gate {0xe, "L2_snoop_inv_sh"}, 2557c478bd9Sstevel@tonic-gate {0xf, "L2_rd_miss"}, 2567c478bd9Sstevel@tonic-gate {0x10, "PC_rd"}, 2577c478bd9Sstevel@tonic-gate {0x11, "SI_snoop_sh"}, 2587c478bd9Sstevel@tonic-gate {0x12, "SI_ciq_flow_sh"}, 2597c478bd9Sstevel@tonic-gate {0x13, "Re_DC_miss"}, 2607c478bd9Sstevel@tonic-gate {0x14, "SW_count_NOP"}, 2617c478bd9Sstevel@tonic-gate {0x15, "IU_stat_br_miss_taken"}, 2627c478bd9Sstevel@tonic-gate {0x16, "IU_stat_br_count_untaken"}, 2637c478bd9Sstevel@tonic-gate {0x17, "HW_pf_exec"}, 2647c478bd9Sstevel@tonic-gate {0x18, "FA_pipe_completion"}, 2657c478bd9Sstevel@tonic-gate {0x19, "SSM_L3_wb_remote"}, 2667c478bd9Sstevel@tonic-gate {0x1a, "SSM_L3_miss_local"}, 2677c478bd9Sstevel@tonic-gate {0x1b, "SSM_L3_miss_mtag_remote"}, 2687c478bd9Sstevel@tonic-gate {0x1c, "SW_pf_str_trapped"}, 2697c478bd9Sstevel@tonic-gate {0x1d, "SW_pf_PC_installed"}, 2707c478bd9Sstevel@tonic-gate {0x1e, "IPB_to_IC_fill"}, 2717c478bd9Sstevel@tonic-gate {0x1f, "L2_write_miss"}, 2727c478bd9Sstevel@tonic-gate {0x20, "MC_reads_0_sh"}, 2737c478bd9Sstevel@tonic-gate {0x21, "MC_reads_1_sh"}, 2747c478bd9Sstevel@tonic-gate {0x22, "MC_reads_2_sh"}, 2757c478bd9Sstevel@tonic-gate {0x23, "MC_reads_3_sh"}, 2767c478bd9Sstevel@tonic-gate {0x24, "MC_stalls_0_sh"}, 2777c478bd9Sstevel@tonic-gate {0x25, "MC_stalls_2_sh"}, 2787c478bd9Sstevel@tonic-gate {0x26, "L2_hit_other_half"}, 2797c478bd9Sstevel@tonic-gate {0x28, "L3_rd_miss"}, 2807c478bd9Sstevel@tonic-gate {0x29, "Re_L2_miss"}, 2817c478bd9Sstevel@tonic-gate {0x2a, "IC_miss_cancelled"}, 2827c478bd9Sstevel@tonic-gate {0x2b, "DC_wr_miss"}, 2837c478bd9Sstevel@tonic-gate {0x2c, "L3_hit_I_state_sh"}, 2847c478bd9Sstevel@tonic-gate {0x2d, "SI_RTS_src_data"}, 2857c478bd9Sstevel@tonic-gate {0x2e, "L2_IC_miss"}, 2867c478bd9Sstevel@tonic-gate {0x2f, "SSM_new_transaction_sh"}, 2877c478bd9Sstevel@tonic-gate {0x30, "L2_SW_pf_miss"}, 2887c478bd9Sstevel@tonic-gate {0x31, "L2_wb"}, 2897c478bd9Sstevel@tonic-gate {0x32, "L2_wb_sh"}, 2907c478bd9Sstevel@tonic-gate {0x33, "L2_snoop_cb_sh"}, 2917c478bd9Sstevel@tonic-gate {NT_END, ""} 2927c478bd9Sstevel@tonic-gate }; 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate 2957c478bd9Sstevel@tonic-gate #define US3all_EVENTS_1 \ 2967c478bd9Sstevel@tonic-gate {0x3, "IC_miss_cancelled"}, \ 2977c478bd9Sstevel@tonic-gate {0x5, "Re_FPU_bypass"}, \ 2987c478bd9Sstevel@tonic-gate {0x6, "Re_DC_miss"}, \ 2997c478bd9Sstevel@tonic-gate {0x7, "Re_EC_miss"}, \ 3007c478bd9Sstevel@tonic-gate {0x8, "IC_miss"}, \ 3017c478bd9Sstevel@tonic-gate {0x9, "DC_rd_miss"}, \ 3027c478bd9Sstevel@tonic-gate {0xa, "DC_wr_miss"}, \ 3037c478bd9Sstevel@tonic-gate {0xb, "Rstall_FP_use"}, \ 3047c478bd9Sstevel@tonic-gate {0xc, "EC_misses"}, \ 3057c478bd9Sstevel@tonic-gate {0xf, "EC_ic_miss"}, \ 3067c478bd9Sstevel@tonic-gate {0x10, "Re_PC_miss"}, \ 3077c478bd9Sstevel@tonic-gate {0x11, "ITLB_miss"}, \ 3087c478bd9Sstevel@tonic-gate {0x12, "DTLB_miss"}, \ 3097c478bd9Sstevel@tonic-gate {0x13, "WC_miss"}, \ 3107c478bd9Sstevel@tonic-gate {0x14, "WC_snoop_cb"}, \ 3117c478bd9Sstevel@tonic-gate {0x15, "WC_scrubbed"}, \ 3127c478bd9Sstevel@tonic-gate {0x16, "WC_wb_wo_read"}, \ 3137c478bd9Sstevel@tonic-gate {0x18, "PC_soft_hit"}, \ 3147c478bd9Sstevel@tonic-gate {0x19, "PC_snoop_inv"}, \ 3157c478bd9Sstevel@tonic-gate {0x1a, "PC_hard_hit"}, \ 3167c478bd9Sstevel@tonic-gate {0x1b, "PC_port1_rd"}, \ 3177c478bd9Sstevel@tonic-gate {0x1c, "SW_count_1"}, \ 3187c478bd9Sstevel@tonic-gate {0x1d, "IU_Stat_Br_miss_untaken"}, \ 3197c478bd9Sstevel@tonic-gate {0x1e, "IU_Stat_Br_count_untaken"}, \ 3207c478bd9Sstevel@tonic-gate {0x1f, "PC_MS_misses"}, \ 3217c478bd9Sstevel@tonic-gate {0x26, "Re_RAW_miss"}, \ 3227c478bd9Sstevel@tonic-gate {0x27, "FM_pipe_completion"} 3237c478bd9Sstevel@tonic-gate 3247c478bd9Sstevel@tonic-gate #define US3_MC_EVENTS_1 \ 3257c478bd9Sstevel@tonic-gate {0x20, "MC_writes_0"}, \ 3267c478bd9Sstevel@tonic-gate {0x21, "MC_writes_1"}, \ 3277c478bd9Sstevel@tonic-gate {0x22, "MC_writes_2"}, \ 3287c478bd9Sstevel@tonic-gate {0x23, "MC_writes_3"}, \ 3297c478bd9Sstevel@tonic-gate {0x24, "MC_stalls_1"}, \ 3307c478bd9Sstevel@tonic-gate {0x25, "MC_stalls_3"} 3317c478bd9Sstevel@tonic-gate 3327c478bd9Sstevel@tonic-gate #define US3_I_MC_EVENTS_1 \ 3337c478bd9Sstevel@tonic-gate {0x20, "MC_open_bank_cmds"}, \ 3347c478bd9Sstevel@tonic-gate {0x21, "MC_reads"}, \ 3357c478bd9Sstevel@tonic-gate {0x22, "MC_writes"}, \ 3367c478bd9Sstevel@tonic-gate {0x23, "MC_page_close_stall"} 3377c478bd9Sstevel@tonic-gate 3387c478bd9Sstevel@tonic-gate static const struct nametable US3_names1[] = { 3397c478bd9Sstevel@tonic-gate USall_EVENTS_1, 3407c478bd9Sstevel@tonic-gate US3all_EVENTS_1, 3417c478bd9Sstevel@tonic-gate US3_MC_EVENTS_1, 3427c478bd9Sstevel@tonic-gate {0x4, "Re_endian_miss"}, 3437c478bd9Sstevel@tonic-gate {NT_END, ""} 3447c478bd9Sstevel@tonic-gate }; 3457c478bd9Sstevel@tonic-gate 3467c478bd9Sstevel@tonic-gate static const struct nametable US3_PLUS_names1[] = { 3477c478bd9Sstevel@tonic-gate USall_EVENTS_1, 3487c478bd9Sstevel@tonic-gate US3all_EVENTS_1, 3497c478bd9Sstevel@tonic-gate US3_MC_EVENTS_1, 3507c478bd9Sstevel@tonic-gate {0x4, "Re_DC_missovhd"}, 3517c478bd9Sstevel@tonic-gate {0x28, "EC_miss_mtag_remote"}, 3527c478bd9Sstevel@tonic-gate {0x29, "EC_miss_remote"}, 3537c478bd9Sstevel@tonic-gate {NT_END, ""} 3547c478bd9Sstevel@tonic-gate }; 3557c478bd9Sstevel@tonic-gate 3567c478bd9Sstevel@tonic-gate static const struct nametable US3_I_names1[] = { 3577c478bd9Sstevel@tonic-gate USall_EVENTS_1, 3587c478bd9Sstevel@tonic-gate US3all_EVENTS_1, 3597c478bd9Sstevel@tonic-gate US3_I_MC_EVENTS_1, 3607c478bd9Sstevel@tonic-gate {0x4, "Re_DC_missovhd"}, 3617c478bd9Sstevel@tonic-gate {NT_END, ""} 3627c478bd9Sstevel@tonic-gate }; 3637c478bd9Sstevel@tonic-gate 3647c478bd9Sstevel@tonic-gate static const struct nametable US4_PLUS_names1[] = { 3657c478bd9Sstevel@tonic-gate {0x0, "Cycle_cnt"}, 3667c478bd9Sstevel@tonic-gate {0x1, "Instr_cnt"}, 3677c478bd9Sstevel@tonic-gate {0x2, "Dispatch0_other"}, 3687c478bd9Sstevel@tonic-gate {0x3, "DC_wr"}, 3697c478bd9Sstevel@tonic-gate {0x4, "Re_DC_missovhd"}, 3707c478bd9Sstevel@tonic-gate {0x5, "Re_FPU_bypass"}, 3717c478bd9Sstevel@tonic-gate {0x6, "L3_write_hit_RTO"}, 3727c478bd9Sstevel@tonic-gate {0x7, "L2L3_snoop_inv_sh"}, 3737c478bd9Sstevel@tonic-gate {0x8, "IC_L2_req"}, 3747c478bd9Sstevel@tonic-gate {0x9, "DC_rd_miss"}, 3757c478bd9Sstevel@tonic-gate {0xa, "L2_hit_I_state_sh"}, 3767c478bd9Sstevel@tonic-gate {0xb, "L3_write_miss_RTO"}, 3777c478bd9Sstevel@tonic-gate {0xc, "L2_miss"}, 3787c478bd9Sstevel@tonic-gate {0xd, "SI_owned_sh"}, 3797c478bd9Sstevel@tonic-gate {0xe, "SI_RTO_src_data"}, 3807c478bd9Sstevel@tonic-gate {0xf, "SW_pf_duplicate"}, 3817c478bd9Sstevel@tonic-gate {0x10, "IU_stat_jmp_mispred"}, 3827c478bd9Sstevel@tonic-gate {0x11, "ITLB_miss"}, 3837c478bd9Sstevel@tonic-gate {0x12, "DTLB_miss"}, 3847c478bd9Sstevel@tonic-gate {0x13, "WC_miss"}, 3857c478bd9Sstevel@tonic-gate {0x14, "IC_fill"}, 3867c478bd9Sstevel@tonic-gate {0x15, "IU_stat_ret_mispred"}, 3877c478bd9Sstevel@tonic-gate {0x16, "Re_L3_miss"}, 3887c478bd9Sstevel@tonic-gate {0x17, "Re_PFQ_full"}, 3897c478bd9Sstevel@tonic-gate {0x18, "PC_soft_hit"}, 3907c478bd9Sstevel@tonic-gate {0x19, "PC_inv"}, 3917c478bd9Sstevel@tonic-gate {0x1a, "PC_hard_hit"}, 3927c478bd9Sstevel@tonic-gate {0x1b, "IC_pf"}, 3937c478bd9Sstevel@tonic-gate {0x1c, "SW_count_NOP"}, 3947c478bd9Sstevel@tonic-gate {0x1d, "IU_stat_br_miss_untaken"}, 3957c478bd9Sstevel@tonic-gate {0x1e, "IU_stat_br_count_taken"}, 3967c478bd9Sstevel@tonic-gate {0x1f, "PC_miss"}, 3977c478bd9Sstevel@tonic-gate {0x20, "MC_writes_0_sh"}, 3987c478bd9Sstevel@tonic-gate {0x21, "MC_writes_1_sh"}, 3997c478bd9Sstevel@tonic-gate {0x22, "MC_writes_2_sh"}, 4007c478bd9Sstevel@tonic-gate {0x23, "MC_writes_3_sh"}, 4017c478bd9Sstevel@tonic-gate {0x24, "MC_stalls_1_sh"}, 4027c478bd9Sstevel@tonic-gate {0x25, "MC_stalls_3_sh"}, 4037c478bd9Sstevel@tonic-gate {0x26, "Re_RAW_miss"}, 4047c478bd9Sstevel@tonic-gate {0x27, "FM_pipe_completion"}, 4057c478bd9Sstevel@tonic-gate {0x28, "SSM_L3_miss_mtag_remote"}, 4067c478bd9Sstevel@tonic-gate {0x29, "SSM_L3_miss_remote"}, 4077c478bd9Sstevel@tonic-gate {0x2a, "SW_pf_exec"}, 4087c478bd9Sstevel@tonic-gate {0x2b, "SW_pf_str_exec"}, 4097c478bd9Sstevel@tonic-gate {0x2c, "SW_pf_dropped"}, 4107c478bd9Sstevel@tonic-gate {0x2d, "SW_pf_L2_installed"}, 4117c478bd9Sstevel@tonic-gate {0x2f, "L2_HW_pf_miss"}, 4127c478bd9Sstevel@tonic-gate {0x31, "L3_miss"}, 4137c478bd9Sstevel@tonic-gate {0x32, "L3_IC_miss"}, 4147c478bd9Sstevel@tonic-gate {0x33, "L3_SW_pf_miss"}, 4157c478bd9Sstevel@tonic-gate {0x34, "L3_hit_other_half"}, 4167c478bd9Sstevel@tonic-gate {0x35, "L3_wb"}, 4177c478bd9Sstevel@tonic-gate {0x36, "L3_wb_sh"}, 4187c478bd9Sstevel@tonic-gate {0x37, "L2L3_snoop_cb_sh"}, 4197c478bd9Sstevel@tonic-gate {NT_END, ""} 4207c478bd9Sstevel@tonic-gate }; 4217c478bd9Sstevel@tonic-gate 4227c478bd9Sstevel@tonic-gate static const struct nametable US12_names1[] = { 4237c478bd9Sstevel@tonic-gate USall_EVENTS_1, 4247c478bd9Sstevel@tonic-gate {0x3, "Dispatch0_FP_use"}, 4257c478bd9Sstevel@tonic-gate {0x8, "IC_hit"}, 4267c478bd9Sstevel@tonic-gate {0x9, "DC_rd_hit"}, 4277c478bd9Sstevel@tonic-gate {0xa, "DC_wr_hit"}, 4287c478bd9Sstevel@tonic-gate {0xb, "Load_use_RAW"}, 4297c478bd9Sstevel@tonic-gate {0xc, "EC_hit"}, 4307c478bd9Sstevel@tonic-gate {0xf, "EC_ic_hit"}, 4317c478bd9Sstevel@tonic-gate {NT_END, ""} 4327c478bd9Sstevel@tonic-gate }; 4337c478bd9Sstevel@tonic-gate 4347c478bd9Sstevel@tonic-gate static const struct nametable *US12_names[2] = { 4357c478bd9Sstevel@tonic-gate US12_names0, 4367c478bd9Sstevel@tonic-gate US12_names1 4377c478bd9Sstevel@tonic-gate }; 4387c478bd9Sstevel@tonic-gate 4397c478bd9Sstevel@tonic-gate static const struct nametable *US3_names[2] = { 4407c478bd9Sstevel@tonic-gate US3_names0, 4417c478bd9Sstevel@tonic-gate US3_names1 4427c478bd9Sstevel@tonic-gate }; 4437c478bd9Sstevel@tonic-gate 4447c478bd9Sstevel@tonic-gate static const struct nametable *US3_PLUS_names[2] = { 4457c478bd9Sstevel@tonic-gate US3_PLUS_names0, 4467c478bd9Sstevel@tonic-gate US3_PLUS_names1 4477c478bd9Sstevel@tonic-gate }; 4487c478bd9Sstevel@tonic-gate 4497c478bd9Sstevel@tonic-gate static const struct nametable *US4_PLUS_names[2] = { 4507c478bd9Sstevel@tonic-gate US4_PLUS_names0, 4517c478bd9Sstevel@tonic-gate US4_PLUS_names1 4527c478bd9Sstevel@tonic-gate }; 4537c478bd9Sstevel@tonic-gate 4547c478bd9Sstevel@tonic-gate static const struct nametable *US3_I_names[2] = { 4557c478bd9Sstevel@tonic-gate US3_I_names0, 4567c478bd9Sstevel@tonic-gate US3_I_names1 4577c478bd9Sstevel@tonic-gate }; 4587c478bd9Sstevel@tonic-gate 459*c7a079a8SJonathan Haslam static const us_generic_event_t US12_generic_names0[] = { 460*c7a079a8SJonathan Haslam { "PAPI_tot_cyc", "Cycle_cnt" }, 461*c7a079a8SJonathan Haslam { "PAPI_tot_ins", "Instr_cnt" }, 462*c7a079a8SJonathan Haslam { "PAPI_tot_iis", "Instr_cnt" }, 463*c7a079a8SJonathan Haslam { "PAPI_l1_dcr", "DC_rd" }, 464*c7a079a8SJonathan Haslam { "PAPI_l1_dcw", "DC_wr" }, 465*c7a079a8SJonathan Haslam { "PAPI_l1_ica", "IC_ref" }, 466*c7a079a8SJonathan Haslam { "PAPI_l2_tca", "EC_ref" }, 467*c7a079a8SJonathan Haslam { "PAPI_l2_dch", "EC_rd_hit" }, 468*c7a079a8SJonathan Haslam { "PAPI_ca_inv", "EC_snoop_inv" }, 469*c7a079a8SJonathan Haslam CPC_GEN_END 470*c7a079a8SJonathan Haslam }; 471*c7a079a8SJonathan Haslam 472*c7a079a8SJonathan Haslam static const us_generic_event_t US12_generic_names1[] = { 473*c7a079a8SJonathan Haslam { "PAPI_tot_cyc", "Cycle_cnt" }, 474*c7a079a8SJonathan Haslam { "PAPI_tot_ins", "Instr_cnt" }, 475*c7a079a8SJonathan Haslam { "PAPI_tot_iis", "Instr_cnt" }, 476*c7a079a8SJonathan Haslam { "PAPI_br_msp", "Dispatch0_mispred" }, 477*c7a079a8SJonathan Haslam { "PAPI_ca_snp", "EC_snoop_cb" }, 478*c7a079a8SJonathan Haslam { "PAPI_l1_ich", "IC_hit" }, 479*c7a079a8SJonathan Haslam { "PAPI_l2_tch", "EC_hit" }, 480*c7a079a8SJonathan Haslam { "PAPI_l2_ich", "EC_ic_hit" }, 481*c7a079a8SJonathan Haslam CPC_GEN_END 482*c7a079a8SJonathan Haslam }; 483*c7a079a8SJonathan Haslam 484*c7a079a8SJonathan Haslam static const us_generic_event_t US3_generic_names0[] = { 485*c7a079a8SJonathan Haslam { "PAPI_tot_cyc", "Cycle_cnt" }, 486*c7a079a8SJonathan Haslam { "PAPI_tot_ins", "Instr_cnt" }, 487*c7a079a8SJonathan Haslam { "PAPI_tot_iis", "Instr_cnt" }, 488*c7a079a8SJonathan Haslam { "PAPI_fad_ins", "FA_pipe_completion" }, 489*c7a079a8SJonathan Haslam { "PAPI_l1_dcr", "DC_rd" }, 490*c7a079a8SJonathan Haslam { "PAPI_l1_dcw", "DC_wr" }, 491*c7a079a8SJonathan Haslam { "PAPI_l1_ica", "IC_ref" }, 492*c7a079a8SJonathan Haslam { "PAPI_l2_tca", "EC_ref" }, 493*c7a079a8SJonathan Haslam { "PAPI_l2_ldm", "EC_rd_miss" }, 494*c7a079a8SJonathan Haslam { "PAPI_ca_inv", "EC_snoop_inv" }, 495*c7a079a8SJonathan Haslam { "PAPI_br_tkn", "IU_Stat_Br_count_taken" }, 496*c7a079a8SJonathan Haslam CPC_GEN_END 497*c7a079a8SJonathan Haslam }; 498*c7a079a8SJonathan Haslam 499*c7a079a8SJonathan Haslam static const us_generic_event_t US3_generic_names1[] = { 500*c7a079a8SJonathan Haslam { "PAPI_tot_cyc", "Cycle_cnt" }, 501*c7a079a8SJonathan Haslam { "PAPI_tot_ins", "Instr_cnt" }, 502*c7a079a8SJonathan Haslam { "PAPI_tot_iis", "Instr_cnt" }, 503*c7a079a8SJonathan Haslam { "PAPI_fml_ins", "FM_pipe_completion" }, 504*c7a079a8SJonathan Haslam { "PAPI_l1_icm", "IC_miss" }, 505*c7a079a8SJonathan Haslam { "PAPI_l1_ldm", "DC_rd_miss" }, 506*c7a079a8SJonathan Haslam { "PAPI_l1_stm", "DC_wr_miss" }, 507*c7a079a8SJonathan Haslam { "PAPI_l2_tcm", "EC_misses" }, 508*c7a079a8SJonathan Haslam { "PAPI_l2_icm", "EC_ic_miss" }, 509*c7a079a8SJonathan Haslam { "PAPI_tlb_dm", "DTLB_miss" }, 510*c7a079a8SJonathan Haslam { "PAPI_tlb_im", "ITLB_miss" }, 511*c7a079a8SJonathan Haslam { "PAPI_br_ntk", "IU_Stat_Br_count_untaken" }, 512*c7a079a8SJonathan Haslam { "PAPI_br_msp", "Dispatch0_mispred" }, 513*c7a079a8SJonathan Haslam { "PAPI_ca_snp", "EC_snoop_cb" }, 514*c7a079a8SJonathan Haslam CPC_GEN_END 515*c7a079a8SJonathan Haslam }; 516*c7a079a8SJonathan Haslam 517*c7a079a8SJonathan Haslam static const us_generic_event_t US4_PLUS_generic_names0[] = { 518*c7a079a8SJonathan Haslam { "PAPI_tot_cyc", "Cycle_cnt" }, 519*c7a079a8SJonathan Haslam { "PAPI_tot_ins", "Instr_cnt" }, 520*c7a079a8SJonathan Haslam { "PAPI_tot_iis", "Instr_cnt" }, 521*c7a079a8SJonathan Haslam { "PAPI_fma_ins", "FA_pipe_completion" }, 522*c7a079a8SJonathan Haslam { "PAPI_l1_dcr", "DC_rd" }, 523*c7a079a8SJonathan Haslam { "PAPI_l1_stm", "DC_wr_miss" }, 524*c7a079a8SJonathan Haslam { "PAPI_l1_ica", "IC_ref" }, 525*c7a079a8SJonathan Haslam { "PAPI_l2_tca", "L2_ref" }, 526*c7a079a8SJonathan Haslam { "PAPI_l2_ldm", "L2_rd_miss" }, 527*c7a079a8SJonathan Haslam { "PAPI_l2_icm", "L2_IC_miss" }, 528*c7a079a8SJonathan Haslam { "PAPI_l2_stm", "L2_write_miss" }, 529*c7a079a8SJonathan Haslam { "PAPI_l3_ldm", "L3_rd_miss" }, 530*c7a079a8SJonathan Haslam { "PAPI_br_ntk", "IU_stat_br_count_untaken" }, 531*c7a079a8SJonathan Haslam CPC_GEN_END 532*c7a079a8SJonathan Haslam }; 533*c7a079a8SJonathan Haslam 534*c7a079a8SJonathan Haslam static const us_generic_event_t US4_PLUS_generic_names1[] = { 535*c7a079a8SJonathan Haslam { "PAPI_tot_cyc", "Cycle_cnt" }, 536*c7a079a8SJonathan Haslam { "PAPI_tot_ins", "Instr_cnt" }, 537*c7a079a8SJonathan Haslam { "PAPI_tot_iis", "Instr_cnt" }, 538*c7a079a8SJonathan Haslam { "PAPI_fml_ins", "FM_pipe_completion" }, 539*c7a079a8SJonathan Haslam { "PAPI_l1_icm", "IC_L2_req" }, 540*c7a079a8SJonathan Haslam { "PAPI_l1_ldm", "DC_rd_miss" }, 541*c7a079a8SJonathan Haslam { "PAPI_l1_dcw", "DC_wr" }, 542*c7a079a8SJonathan Haslam { "PAPI_l2_tcm", "L2_miss" }, 543*c7a079a8SJonathan Haslam { "PAPI_l3_tcm", "L3_miss" }, 544*c7a079a8SJonathan Haslam { "PAPI_l3_icm", "L3_IC_miss" }, 545*c7a079a8SJonathan Haslam { "PAPI_tlb_im", "ITLB_miss" }, 546*c7a079a8SJonathan Haslam { "PAPI_tlb_dm", "DTLB_miss" }, 547*c7a079a8SJonathan Haslam { "PAPI_br_tkn", "IU_stat_br_count_taken" }, 548*c7a079a8SJonathan Haslam CPC_GEN_END 549*c7a079a8SJonathan Haslam }; 550*c7a079a8SJonathan Haslam 551*c7a079a8SJonathan Haslam static const us_generic_event_t *US12_generic_names[2] = { 552*c7a079a8SJonathan Haslam US12_generic_names0, 553*c7a079a8SJonathan Haslam US12_generic_names1 554*c7a079a8SJonathan Haslam }; 555*c7a079a8SJonathan Haslam 556*c7a079a8SJonathan Haslam static const us_generic_event_t *US3_generic_names[2] = { 557*c7a079a8SJonathan Haslam US3_generic_names0, 558*c7a079a8SJonathan Haslam US3_generic_names1 559*c7a079a8SJonathan Haslam }; 560*c7a079a8SJonathan Haslam 561*c7a079a8SJonathan Haslam static const us_generic_event_t *US4_PLUS_generic_names[2] = { 562*c7a079a8SJonathan Haslam US4_PLUS_generic_names0, 563*c7a079a8SJonathan Haslam US4_PLUS_generic_names1 564*c7a079a8SJonathan Haslam }; 565*c7a079a8SJonathan Haslam 5667c478bd9Sstevel@tonic-gate static const struct nametable **events; 567*c7a079a8SJonathan Haslam static const us_generic_event_t **generic_events; 5687c478bd9Sstevel@tonic-gate static const char *us_impl_name; 5697c478bd9Sstevel@tonic-gate static const char *us_cpuref; 5707c478bd9Sstevel@tonic-gate static char *pic_events[2]; 5717c478bd9Sstevel@tonic-gate static uint16_t pcr_pic_mask; 5727c478bd9Sstevel@tonic-gate 5737c478bd9Sstevel@tonic-gate #define CPU_REF_URL " Documentation for Sun processors can be found at: " \ 5747c478bd9Sstevel@tonic-gate "http://www.sun.com/processors/manuals" 5757c478bd9Sstevel@tonic-gate 5767c478bd9Sstevel@tonic-gate static const char *us_2_ref = "See the \"UltraSPARC I/II User\'s Manual\" " 5777c478bd9Sstevel@tonic-gate "(Part No. 802-7220-02) " 5787c478bd9Sstevel@tonic-gate "for descriptions of these events." CPU_REF_URL; 5797c478bd9Sstevel@tonic-gate 5807c478bd9Sstevel@tonic-gate static const char *us_3cu_ref = "See the \"UltraSPARC III Cu User's Manual\" " 5817c478bd9Sstevel@tonic-gate "for descriptions of these events." CPU_REF_URL; 5827c478bd9Sstevel@tonic-gate 5837c478bd9Sstevel@tonic-gate static const char *us4_plus_ref = "See the \"UltraSPARC IV+ User's Manual\" " 5847c478bd9Sstevel@tonic-gate "for descriptions of these events." CPU_REF_URL; 5857c478bd9Sstevel@tonic-gate 5867c478bd9Sstevel@tonic-gate static const char *us_3i_ref = "See the \"UltraSPARC IIIi User's Manual\" " 5877c478bd9Sstevel@tonic-gate "for descriptions of these events." CPU_REF_URL; 5887c478bd9Sstevel@tonic-gate 5897c478bd9Sstevel@tonic-gate static int 5907c478bd9Sstevel@tonic-gate us_pcbe_init(void) 5917c478bd9Sstevel@tonic-gate { 5927c478bd9Sstevel@tonic-gate const struct nametable *n; 593*c7a079a8SJonathan Haslam const us_generic_event_t *gevp; 5947c478bd9Sstevel@tonic-gate int i; 5957c478bd9Sstevel@tonic-gate size_t size; 5967c478bd9Sstevel@tonic-gate 5977c478bd9Sstevel@tonic-gate /* 5987c478bd9Sstevel@tonic-gate * Discover type of CPU 5997c478bd9Sstevel@tonic-gate * 6007c478bd9Sstevel@tonic-gate * Point nametable to that CPU's table 6017c478bd9Sstevel@tonic-gate */ 6027c478bd9Sstevel@tonic-gate switch (ULTRA_VER_IMPL(ultra_getver())) { 6037c478bd9Sstevel@tonic-gate case SPITFIRE_IMPL: 6047c478bd9Sstevel@tonic-gate case BLACKBIRD_IMPL: 6057c478bd9Sstevel@tonic-gate case SABRE_IMPL: 6067c478bd9Sstevel@tonic-gate case HUMMBRD_IMPL: 6077c478bd9Sstevel@tonic-gate events = US12_names; 608*c7a079a8SJonathan Haslam generic_events = US12_generic_names; 6097c478bd9Sstevel@tonic-gate us_impl_name = "UltraSPARC I&II"; 6107c478bd9Sstevel@tonic-gate us_cpuref = us_2_ref; 6117c478bd9Sstevel@tonic-gate pcr_pic_mask = CPC_ULTRA2_PCR_PIC_MASK; 6127c478bd9Sstevel@tonic-gate us_pcbe_ops.pcbe_caps &= ~CPC_CAP_OVERFLOW_INTERRUPT; 6137c478bd9Sstevel@tonic-gate break; 6147c478bd9Sstevel@tonic-gate case CHEETAH_IMPL: 6157c478bd9Sstevel@tonic-gate events = US3_names; 616*c7a079a8SJonathan Haslam generic_events = US3_generic_names; 6177c478bd9Sstevel@tonic-gate us_impl_name = "UltraSPARC III"; 6187c478bd9Sstevel@tonic-gate us_cpuref = us_3cu_ref; 6197c478bd9Sstevel@tonic-gate pcr_pic_mask = CPC_ULTRA3_PCR_PIC_MASK; 6207c478bd9Sstevel@tonic-gate break; 6217c478bd9Sstevel@tonic-gate case CHEETAH_PLUS_IMPL: 6227c478bd9Sstevel@tonic-gate case JAGUAR_IMPL: 6237c478bd9Sstevel@tonic-gate events = US3_PLUS_names; 624*c7a079a8SJonathan Haslam generic_events = US3_generic_names; 6257c478bd9Sstevel@tonic-gate us_impl_name = "UltraSPARC III+ & IV"; 6267c478bd9Sstevel@tonic-gate us_cpuref = us_3cu_ref; 6277c478bd9Sstevel@tonic-gate pcr_pic_mask = CPC_ULTRA3_PCR_PIC_MASK; 6287c478bd9Sstevel@tonic-gate break; 6297c478bd9Sstevel@tonic-gate case PANTHER_IMPL: 6307c478bd9Sstevel@tonic-gate events = US4_PLUS_names; 631*c7a079a8SJonathan Haslam generic_events = US4_PLUS_generic_names; 6327c478bd9Sstevel@tonic-gate us_impl_name = "UltraSPARC IV+"; 6337c478bd9Sstevel@tonic-gate us_cpuref = us4_plus_ref; 6347c478bd9Sstevel@tonic-gate pcr_pic_mask = CPC_ULTRA3_PCR_PIC_MASK; 6357c478bd9Sstevel@tonic-gate break; 6367c478bd9Sstevel@tonic-gate case JALAPENO_IMPL: 6377c478bd9Sstevel@tonic-gate case SERRANO_IMPL: 6387c478bd9Sstevel@tonic-gate events = US3_I_names; 639*c7a079a8SJonathan Haslam generic_events = US3_generic_names; 6407c478bd9Sstevel@tonic-gate us_impl_name = "UltraSPARC IIIi & IIIi+"; 6417c478bd9Sstevel@tonic-gate us_cpuref = us_3i_ref; 6427c478bd9Sstevel@tonic-gate pcr_pic_mask = CPC_ULTRA3_PCR_PIC_MASK; 6437c478bd9Sstevel@tonic-gate break; 6447c478bd9Sstevel@tonic-gate default: 6457c478bd9Sstevel@tonic-gate return (-1); 6467c478bd9Sstevel@tonic-gate } 6477c478bd9Sstevel@tonic-gate 6487c478bd9Sstevel@tonic-gate /* 6497c478bd9Sstevel@tonic-gate * Initialize the list of events for each PIC. 6507c478bd9Sstevel@tonic-gate * Do two passes: one to compute the size necessary and another 6517c478bd9Sstevel@tonic-gate * to copy the strings. Need room for event, comma, and NULL terminator. 6527c478bd9Sstevel@tonic-gate */ 6537c478bd9Sstevel@tonic-gate for (i = 0; i < 2; i++) { 6547c478bd9Sstevel@tonic-gate size = 0; 6557c478bd9Sstevel@tonic-gate for (n = events[i]; n->bits != NT_END; n++) 6567c478bd9Sstevel@tonic-gate size += strlen(n->name) + 1; 657*c7a079a8SJonathan Haslam for (gevp = generic_events[i]; gevp->name != NULL; gevp++) 658*c7a079a8SJonathan Haslam size += strlen(gevp->name) + 1; 6597c478bd9Sstevel@tonic-gate pic_events[i] = kmem_alloc(size + 1, KM_SLEEP); 6607c478bd9Sstevel@tonic-gate *pic_events[i] = '\0'; 6617c478bd9Sstevel@tonic-gate for (n = events[i]; n->bits != NT_END; n++) { 6627c478bd9Sstevel@tonic-gate (void) strcat(pic_events[i], n->name); 6637c478bd9Sstevel@tonic-gate (void) strcat(pic_events[i], ","); 6647c478bd9Sstevel@tonic-gate } 665*c7a079a8SJonathan Haslam for (gevp = generic_events[i]; gevp->name != NULL; gevp++) { 666*c7a079a8SJonathan Haslam (void) strcat(pic_events[i], gevp->name); 667*c7a079a8SJonathan Haslam (void) strcat(pic_events[i], ","); 668*c7a079a8SJonathan Haslam } 669*c7a079a8SJonathan Haslam 6707c478bd9Sstevel@tonic-gate /* 6717c478bd9Sstevel@tonic-gate * Remove trailing comma. 6727c478bd9Sstevel@tonic-gate */ 6737c478bd9Sstevel@tonic-gate pic_events[i][size - 1] = '\0'; 6747c478bd9Sstevel@tonic-gate } 6757c478bd9Sstevel@tonic-gate 6767c478bd9Sstevel@tonic-gate return (0); 6777c478bd9Sstevel@tonic-gate } 6787c478bd9Sstevel@tonic-gate 6797c478bd9Sstevel@tonic-gate static uint_t 6807c478bd9Sstevel@tonic-gate us_pcbe_ncounters(void) 6817c478bd9Sstevel@tonic-gate { 6827c478bd9Sstevel@tonic-gate return (2); 6837c478bd9Sstevel@tonic-gate } 6847c478bd9Sstevel@tonic-gate 6857c478bd9Sstevel@tonic-gate static const char * 6867c478bd9Sstevel@tonic-gate us_pcbe_impl_name(void) 6877c478bd9Sstevel@tonic-gate { 6887c478bd9Sstevel@tonic-gate return (us_impl_name); 6897c478bd9Sstevel@tonic-gate } 6907c478bd9Sstevel@tonic-gate 6917c478bd9Sstevel@tonic-gate static const char * 6927c478bd9Sstevel@tonic-gate us_pcbe_cpuref(void) 6937c478bd9Sstevel@tonic-gate { 6947c478bd9Sstevel@tonic-gate return (us_cpuref); 6957c478bd9Sstevel@tonic-gate } 6967c478bd9Sstevel@tonic-gate 6977c478bd9Sstevel@tonic-gate static char * 6987c478bd9Sstevel@tonic-gate us_pcbe_list_events(uint_t picnum) 6997c478bd9Sstevel@tonic-gate { 7007c478bd9Sstevel@tonic-gate ASSERT(picnum >= 0 && picnum < cpc_ncounters); 7017c478bd9Sstevel@tonic-gate 7027c478bd9Sstevel@tonic-gate return (pic_events[picnum]); 7037c478bd9Sstevel@tonic-gate } 7047c478bd9Sstevel@tonic-gate 7057c478bd9Sstevel@tonic-gate static char * 7067c478bd9Sstevel@tonic-gate us_pcbe_list_attrs(void) 7077c478bd9Sstevel@tonic-gate { 7087c478bd9Sstevel@tonic-gate return (""); 7097c478bd9Sstevel@tonic-gate } 7107c478bd9Sstevel@tonic-gate 711*c7a079a8SJonathan Haslam static const us_generic_event_t * 712*c7a079a8SJonathan Haslam find_generic_event(int regno, char *name) 713*c7a079a8SJonathan Haslam { 714*c7a079a8SJonathan Haslam const us_generic_event_t *gevp; 715*c7a079a8SJonathan Haslam 716*c7a079a8SJonathan Haslam for (gevp = generic_events[regno]; gevp->name != NULL; gevp++) 717*c7a079a8SJonathan Haslam if (strcmp(name, gevp->name) == 0) 718*c7a079a8SJonathan Haslam return (gevp); 719*c7a079a8SJonathan Haslam 720*c7a079a8SJonathan Haslam return (NULL); 721*c7a079a8SJonathan Haslam } 722*c7a079a8SJonathan Haslam 7237c478bd9Sstevel@tonic-gate static const struct nametable * 7247c478bd9Sstevel@tonic-gate find_event(int regno, char *name) 7257c478bd9Sstevel@tonic-gate { 7267c478bd9Sstevel@tonic-gate const struct nametable *n; 7277c478bd9Sstevel@tonic-gate 7287c478bd9Sstevel@tonic-gate n = events[regno]; 7297c478bd9Sstevel@tonic-gate 7307c478bd9Sstevel@tonic-gate for (; n->bits != NT_END; n++) 7317c478bd9Sstevel@tonic-gate if (strcmp(name, n->name) == 0) 7327c478bd9Sstevel@tonic-gate return (n); 7337c478bd9Sstevel@tonic-gate 7347c478bd9Sstevel@tonic-gate return (NULL); 7357c478bd9Sstevel@tonic-gate } 7367c478bd9Sstevel@tonic-gate 7377c478bd9Sstevel@tonic-gate static uint64_t 7387c478bd9Sstevel@tonic-gate us_pcbe_event_coverage(char *event) 7397c478bd9Sstevel@tonic-gate { 7407c478bd9Sstevel@tonic-gate uint64_t bitmap = 0; 7417c478bd9Sstevel@tonic-gate 742*c7a079a8SJonathan Haslam if ((find_event(0, event) != NULL) || 743*c7a079a8SJonathan Haslam (find_generic_event(0, event) != NULL)) 7447c478bd9Sstevel@tonic-gate bitmap = 0x1; 745*c7a079a8SJonathan Haslam if ((find_event(1, event) != NULL) || 746*c7a079a8SJonathan Haslam (find_generic_event(1, event) != NULL)) 7477c478bd9Sstevel@tonic-gate bitmap |= 0x2; 7487c478bd9Sstevel@tonic-gate 7497c478bd9Sstevel@tonic-gate return (bitmap); 7507c478bd9Sstevel@tonic-gate } 7517c478bd9Sstevel@tonic-gate 7527c478bd9Sstevel@tonic-gate /* 7537c478bd9Sstevel@tonic-gate * These processors cannot tell which counter overflowed. The PCBE interface 7547c478bd9Sstevel@tonic-gate * requires such processors to act as if _all_ counters had overflowed. 7557c478bd9Sstevel@tonic-gate */ 7567c478bd9Sstevel@tonic-gate static uint64_t 7577c478bd9Sstevel@tonic-gate us_pcbe_overflow_bitmap(void) 7587c478bd9Sstevel@tonic-gate { 7597c478bd9Sstevel@tonic-gate return (0x3); 7607c478bd9Sstevel@tonic-gate } 7617c478bd9Sstevel@tonic-gate 7627c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 7637c478bd9Sstevel@tonic-gate static int 7647c478bd9Sstevel@tonic-gate us_pcbe_configure(uint_t picnum, char *event, uint64_t preset, uint32_t flags, 7657c478bd9Sstevel@tonic-gate uint_t nattrs, kcpc_attr_t *attrs, void **data, void *token) 7667c478bd9Sstevel@tonic-gate { 7677c478bd9Sstevel@tonic-gate us_pcbe_config_t *conf; 7687c478bd9Sstevel@tonic-gate const struct nametable *n; 769*c7a079a8SJonathan Haslam const us_generic_event_t *gevp; 7707c478bd9Sstevel@tonic-gate us_pcbe_config_t *other_config; 7717c478bd9Sstevel@tonic-gate 7727c478bd9Sstevel@tonic-gate /* 7737c478bd9Sstevel@tonic-gate * If we've been handed an existing configuration, we need only preset 7747c478bd9Sstevel@tonic-gate * the counter value. 7757c478bd9Sstevel@tonic-gate */ 7767c478bd9Sstevel@tonic-gate if (*data != NULL) { 7777c478bd9Sstevel@tonic-gate conf = *data; 7787c478bd9Sstevel@tonic-gate conf->us_pic = (uint32_t)preset; 7797c478bd9Sstevel@tonic-gate return (0); 7807c478bd9Sstevel@tonic-gate } 7817c478bd9Sstevel@tonic-gate 7827c478bd9Sstevel@tonic-gate if (picnum < 0 || picnum > 1) 7837c478bd9Sstevel@tonic-gate return (CPC_INVALID_PICNUM); 7847c478bd9Sstevel@tonic-gate 7857c478bd9Sstevel@tonic-gate if (nattrs != 0) 7867c478bd9Sstevel@tonic-gate return (CPC_INVALID_ATTRIBUTE); 7877c478bd9Sstevel@tonic-gate 7887c478bd9Sstevel@tonic-gate /* 7897c478bd9Sstevel@tonic-gate * Find other requests that will be programmed with this one, and ensure 7907c478bd9Sstevel@tonic-gate * the flags don't conflict. 7917c478bd9Sstevel@tonic-gate */ 7927c478bd9Sstevel@tonic-gate if (((other_config = kcpc_next_config(token, NULL, NULL)) != NULL) && 7937c478bd9Sstevel@tonic-gate (other_config->us_flags != flags)) 7947c478bd9Sstevel@tonic-gate return (CPC_CONFLICTING_REQS); 7957c478bd9Sstevel@tonic-gate 796*c7a079a8SJonathan Haslam if ((n = find_event(picnum, event)) == NULL) { 797*c7a079a8SJonathan Haslam if ((gevp = find_generic_event(picnum, event)) != NULL) { 798*c7a079a8SJonathan Haslam n = find_event(picnum, gevp->event); 799*c7a079a8SJonathan Haslam ASSERT(n != NULL); 800*c7a079a8SJonathan Haslam } else { 8017c478bd9Sstevel@tonic-gate return (CPC_INVALID_EVENT); 802*c7a079a8SJonathan Haslam } 803*c7a079a8SJonathan Haslam } 8047c478bd9Sstevel@tonic-gate 8057c478bd9Sstevel@tonic-gate conf = kmem_alloc(sizeof (us_pcbe_config_t), KM_SLEEP); 8067c478bd9Sstevel@tonic-gate 8077c478bd9Sstevel@tonic-gate conf->us_picno = picnum; 8087c478bd9Sstevel@tonic-gate conf->us_bits = (uint32_t)n->bits; 8097c478bd9Sstevel@tonic-gate conf->us_flags = flags; 8107c478bd9Sstevel@tonic-gate conf->us_pic = (uint32_t)preset; 8117c478bd9Sstevel@tonic-gate 8127c478bd9Sstevel@tonic-gate *data = conf; 8137c478bd9Sstevel@tonic-gate return (0); 8147c478bd9Sstevel@tonic-gate } 8157c478bd9Sstevel@tonic-gate 8167c478bd9Sstevel@tonic-gate static void 8177c478bd9Sstevel@tonic-gate us_pcbe_program(void *token) 8187c478bd9Sstevel@tonic-gate { 8197c478bd9Sstevel@tonic-gate us_pcbe_config_t *pic0; 8207c478bd9Sstevel@tonic-gate us_pcbe_config_t *pic1; 8217c478bd9Sstevel@tonic-gate us_pcbe_config_t *tmp; 8227c478bd9Sstevel@tonic-gate us_pcbe_config_t empty = { 1, 0x1c, 0, 0 }; /* SW_count_1 */ 8237c478bd9Sstevel@tonic-gate uint64_t pcr; 8247c478bd9Sstevel@tonic-gate uint64_t curpic; 8257c478bd9Sstevel@tonic-gate 8267c478bd9Sstevel@tonic-gate if ((pic0 = (us_pcbe_config_t *)kcpc_next_config(token, NULL, NULL)) == 8277c478bd9Sstevel@tonic-gate NULL) 8287c478bd9Sstevel@tonic-gate panic("us_pcbe: token %p has no configs", token); 8297c478bd9Sstevel@tonic-gate 8307c478bd9Sstevel@tonic-gate if ((pic1 = kcpc_next_config(token, pic0, NULL)) == NULL) { 8317c478bd9Sstevel@tonic-gate pic1 = ∅ 8327c478bd9Sstevel@tonic-gate empty.us_flags = pic0->us_flags; 8337c478bd9Sstevel@tonic-gate } 8347c478bd9Sstevel@tonic-gate 8357c478bd9Sstevel@tonic-gate if (pic0->us_picno != 0) { 8367c478bd9Sstevel@tonic-gate /* 8377c478bd9Sstevel@tonic-gate * pic0 is counter 1, so if we need the empty config it should 8387c478bd9Sstevel@tonic-gate * be counter 0. 8397c478bd9Sstevel@tonic-gate */ 8407c478bd9Sstevel@tonic-gate empty.us_picno = 0; 8417c478bd9Sstevel@tonic-gate empty.us_bits = 0x14; /* SW_count_0 - won't overflow */ 8427c478bd9Sstevel@tonic-gate tmp = pic0; 8437c478bd9Sstevel@tonic-gate pic0 = pic1; 8447c478bd9Sstevel@tonic-gate pic1 = tmp; 8457c478bd9Sstevel@tonic-gate } 8467c478bd9Sstevel@tonic-gate 8477c478bd9Sstevel@tonic-gate if (pic0->us_picno != 0 || pic1->us_picno != 1) 8487c478bd9Sstevel@tonic-gate panic("us_pcbe: bad config on token %p\n", token); 8497c478bd9Sstevel@tonic-gate 8507c478bd9Sstevel@tonic-gate /* 8517c478bd9Sstevel@tonic-gate * UltraSPARC does not allow pic0 to be configured differently 8527c478bd9Sstevel@tonic-gate * from pic1. If the flags on these two configurations are 8537c478bd9Sstevel@tonic-gate * different, they are incompatible. This condition should be 8547c478bd9Sstevel@tonic-gate * caught at configure time. 8557c478bd9Sstevel@tonic-gate */ 8567c478bd9Sstevel@tonic-gate ASSERT(pic0->us_flags == pic1->us_flags); 8577c478bd9Sstevel@tonic-gate 8587c478bd9Sstevel@tonic-gate ultra_setpcr(allstopped); 8597c478bd9Sstevel@tonic-gate ultra_setpic(((uint64_t)pic1->us_pic << 32) | (uint64_t)pic0->us_pic); 8607c478bd9Sstevel@tonic-gate 8617c478bd9Sstevel@tonic-gate pcr = (pic0->us_bits & pcr_pic_mask) << 8627c478bd9Sstevel@tonic-gate CPC_ULTRA_PCR_PIC0_SHIFT; 8637c478bd9Sstevel@tonic-gate pcr |= (pic1->us_bits & pcr_pic_mask) << 8647c478bd9Sstevel@tonic-gate CPC_ULTRA_PCR_PIC1_SHIFT; 8657c478bd9Sstevel@tonic-gate 8667c478bd9Sstevel@tonic-gate if (pic0->us_flags & CPC_COUNT_USER) 8677c478bd9Sstevel@tonic-gate pcr |= (1ull << CPC_ULTRA_PCR_USR); 8687c478bd9Sstevel@tonic-gate if (pic0->us_flags & CPC_COUNT_SYSTEM) 8697c478bd9Sstevel@tonic-gate pcr |= (1ull << CPC_ULTRA_PCR_SYS); 8707c478bd9Sstevel@tonic-gate 8717c478bd9Sstevel@tonic-gate DTRACE_PROBE1(ultra__pcr, uint64_t, pcr); 8727c478bd9Sstevel@tonic-gate 8737c478bd9Sstevel@tonic-gate ultra_setpcr(pcr); 8747c478bd9Sstevel@tonic-gate 8757c478bd9Sstevel@tonic-gate /* 8767c478bd9Sstevel@tonic-gate * On UltraSPARC, only read-to-read counts are accurate. We cannot 8777c478bd9Sstevel@tonic-gate * expect the value we wrote into the PIC, above, to be there after 8787c478bd9Sstevel@tonic-gate * starting the counter. We must sample the counter value now and use 8797c478bd9Sstevel@tonic-gate * that as the baseline for future samples. 8807c478bd9Sstevel@tonic-gate */ 8817c478bd9Sstevel@tonic-gate curpic = ultra_getpic(); 8827c478bd9Sstevel@tonic-gate pic0->us_pic = (uint32_t)(curpic & PIC0_MASK); 8837c478bd9Sstevel@tonic-gate pic1->us_pic = (uint32_t)(curpic >> 32); 8847c478bd9Sstevel@tonic-gate } 8857c478bd9Sstevel@tonic-gate 8867c478bd9Sstevel@tonic-gate static void 8877c478bd9Sstevel@tonic-gate us_pcbe_allstop(void) 8887c478bd9Sstevel@tonic-gate { 8897c478bd9Sstevel@tonic-gate ultra_setpcr(allstopped); 8907c478bd9Sstevel@tonic-gate } 8917c478bd9Sstevel@tonic-gate 8927c478bd9Sstevel@tonic-gate 8937c478bd9Sstevel@tonic-gate static void 8947c478bd9Sstevel@tonic-gate us_pcbe_sample(void *token) 8957c478bd9Sstevel@tonic-gate { 8967c478bd9Sstevel@tonic-gate uint64_t curpic; 8977c478bd9Sstevel@tonic-gate int64_t diff; 8987c478bd9Sstevel@tonic-gate uint64_t *pic0_data; 8997c478bd9Sstevel@tonic-gate uint64_t *pic1_data; 9007c478bd9Sstevel@tonic-gate uint64_t *dtmp; 9017c478bd9Sstevel@tonic-gate uint64_t tmp; 9027c478bd9Sstevel@tonic-gate us_pcbe_config_t *pic0; 9037c478bd9Sstevel@tonic-gate us_pcbe_config_t *pic1; 9047c478bd9Sstevel@tonic-gate us_pcbe_config_t empty = { 1, 0, 0, 0 }; 9057c478bd9Sstevel@tonic-gate us_pcbe_config_t *ctmp; 9067c478bd9Sstevel@tonic-gate 9077c478bd9Sstevel@tonic-gate curpic = ultra_getpic(); 9087c478bd9Sstevel@tonic-gate 9097c478bd9Sstevel@tonic-gate if ((pic0 = kcpc_next_config(token, NULL, &pic0_data)) == NULL) 9107c478bd9Sstevel@tonic-gate panic("us_pcbe: token %p has no configs", token); 9117c478bd9Sstevel@tonic-gate 9127c478bd9Sstevel@tonic-gate if ((pic1 = kcpc_next_config(token, pic0, &pic1_data)) == NULL) { 9137c478bd9Sstevel@tonic-gate pic1 = ∅ 9147c478bd9Sstevel@tonic-gate pic1_data = &tmp; 9157c478bd9Sstevel@tonic-gate } 9167c478bd9Sstevel@tonic-gate 9177c478bd9Sstevel@tonic-gate if (pic0->us_picno != 0) { 9187c478bd9Sstevel@tonic-gate empty.us_picno = 0; 9197c478bd9Sstevel@tonic-gate ctmp = pic0; 9207c478bd9Sstevel@tonic-gate pic0 = pic1; 9217c478bd9Sstevel@tonic-gate pic1 = ctmp; 9227c478bd9Sstevel@tonic-gate dtmp = pic0_data; 9237c478bd9Sstevel@tonic-gate pic0_data = pic1_data; 9247c478bd9Sstevel@tonic-gate pic1_data = dtmp; 9257c478bd9Sstevel@tonic-gate } 9267c478bd9Sstevel@tonic-gate 9277c478bd9Sstevel@tonic-gate if (pic0->us_picno != 0 || pic1->us_picno != 1) 9287c478bd9Sstevel@tonic-gate panic("us_pcbe: bad config on token %p\n", token); 9297c478bd9Sstevel@tonic-gate 9307c478bd9Sstevel@tonic-gate diff = (curpic & PIC0_MASK) - (uint64_t)pic0->us_pic; 9317c478bd9Sstevel@tonic-gate if (diff < 0) 9327c478bd9Sstevel@tonic-gate diff += (1ll << 32); 9337c478bd9Sstevel@tonic-gate *pic0_data += diff; 9347c478bd9Sstevel@tonic-gate 9357c478bd9Sstevel@tonic-gate diff = (curpic >> 32) - (uint64_t)pic1->us_pic; 9367c478bd9Sstevel@tonic-gate if (diff < 0) 9377c478bd9Sstevel@tonic-gate diff += (1ll << 32); 9387c478bd9Sstevel@tonic-gate *pic1_data += diff; 9397c478bd9Sstevel@tonic-gate 9407c478bd9Sstevel@tonic-gate pic0->us_pic = (uint32_t)(curpic & PIC0_MASK); 9417c478bd9Sstevel@tonic-gate pic1->us_pic = (uint32_t)(curpic >> 32); 9427c478bd9Sstevel@tonic-gate } 9437c478bd9Sstevel@tonic-gate 9447c478bd9Sstevel@tonic-gate static void 9457c478bd9Sstevel@tonic-gate us_pcbe_free(void *config) 9467c478bd9Sstevel@tonic-gate { 9477c478bd9Sstevel@tonic-gate kmem_free(config, sizeof (us_pcbe_config_t)); 9487c478bd9Sstevel@tonic-gate } 9497c478bd9Sstevel@tonic-gate 9507c478bd9Sstevel@tonic-gate 9517c478bd9Sstevel@tonic-gate static struct modlpcbe modlpcbe = { 9527c478bd9Sstevel@tonic-gate &mod_pcbeops, 953820c9f58Skk208521 "UltraSPARC Performance Counters", 9547c478bd9Sstevel@tonic-gate &us_pcbe_ops 9557c478bd9Sstevel@tonic-gate }; 9567c478bd9Sstevel@tonic-gate 9577c478bd9Sstevel@tonic-gate static struct modlinkage modl = { 9587c478bd9Sstevel@tonic-gate MODREV_1, 9597c478bd9Sstevel@tonic-gate &modlpcbe, 9607c478bd9Sstevel@tonic-gate }; 9617c478bd9Sstevel@tonic-gate 9627c478bd9Sstevel@tonic-gate int 9637c478bd9Sstevel@tonic-gate _init(void) 9647c478bd9Sstevel@tonic-gate { 9657c478bd9Sstevel@tonic-gate if (us_pcbe_init() != 0) 9667c478bd9Sstevel@tonic-gate return (ENOTSUP); 9677c478bd9Sstevel@tonic-gate return (mod_install(&modl)); 9687c478bd9Sstevel@tonic-gate } 9697c478bd9Sstevel@tonic-gate 9707c478bd9Sstevel@tonic-gate int 9717c478bd9Sstevel@tonic-gate _fini(void) 9727c478bd9Sstevel@tonic-gate { 9737c478bd9Sstevel@tonic-gate return (mod_remove(&modl)); 9747c478bd9Sstevel@tonic-gate } 9757c478bd9Sstevel@tonic-gate 9767c478bd9Sstevel@tonic-gate int 9777c478bd9Sstevel@tonic-gate _info(struct modinfo *mi) 9787c478bd9Sstevel@tonic-gate { 9797c478bd9Sstevel@tonic-gate return (mod_info(&modl, mi)); 9807c478bd9Sstevel@tonic-gate } 981