[BACK]Return to tprof_x86.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / usr.sbin / tprof / arch

Annotation of src/usr.sbin/tprof/arch/tprof_x86.c, Revision 1.7

1.7     ! knakahar    1: /*     $NetBSD: tprof_x86.c,v 1.6 2018/11/26 07:45:47 knakahara Exp $  */
1.1       maxv        2:
                      3: /*
                      4:  * Copyright (c) 2018 The NetBSD Foundation, Inc.
                      5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to The NetBSD Foundation
                      8:  * by Maxime Villard.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  *
                     19:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     20:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     21:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     22:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     23:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     24:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     25:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     26:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     27:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     28:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     29:  * POSSIBILITY OF SUCH DAMAGE.
                     30:  */
                     31:
                     32: #include <sys/cdefs.h>
                     33: #include <stdio.h>
                     34: #include <stdlib.h>
                     35: #include <stdbool.h>
                     36: #include <string.h>
                     37: #include <unistd.h>
                     38: #include <err.h>
                     39: #include <machine/specialreg.h>
                     40: #include <dev/tprof/tprof_ioctl.h>
                     41: #include "../tprof.h"
                     42:
                     43: int tprof_event_init(uint32_t);
                     44: void tprof_event_list(void);
                     45: void tprof_event_lookup(const char *, struct tprof_param *);
                     46:
                     47: struct name_to_event {
                     48:        const char *name;
                     49:        uint64_t event;
                     50:        uint64_t unit;
                     51:        bool enabled;
                     52: };
                     53:
                     54: struct event_table {
                     55:        const char *tablename;
                     56:        struct name_to_event *names;
                     57:        size_t nevents;
                     58:        struct event_table *next;
                     59: };
                     60:
                     61: static struct event_table *cpuevents = NULL;
                     62:
                     63: static void x86_cpuid(unsigned int *eax, unsigned int *ebx,
                     64:     unsigned int *ecx, unsigned int *edx)
                     65: {
                     66:        asm volatile("cpuid"
                     67:            : "=a" (*eax),
                     68:              "=b" (*ebx),
                     69:              "=c" (*ecx),
                     70:              "=d" (*edx)
                     71:            : "0" (*eax), "2" (*ecx));
                     72: }
                     73:
                     74: /* -------------------------------------------------------------------------- */
                     75:
                     76: /*
                     77:  * Intel Architectural Version 1.
                     78:  */
                     79: static struct name_to_event intel_arch1_names[] = {
                     80:        /* Event Name - Event Select - UMask */
                     81:        { "unhalted-core-cycles",       0x3C, 0x00, true },
                     82:        { "instruction-retired",        0xC0, 0x00, true },
                     83:        { "unhalted-reference-cycles",  0x3C, 0x01, true },
                     84:        { "llc-reference",              0x2E, 0x4F, true },
                     85:        { "llc-misses",                 0x2E, 0x41, true },
                     86:        { "branch-instruction-retired", 0xC4, 0x00, true },
                     87:        { "branch-misses-retired",      0xC5, 0x00, true },
                     88: };
                     89:
                     90: static struct event_table intel_arch1 = {
                     91:        .tablename = "Intel Architectural Version 1",
                     92:        .names = intel_arch1_names,
                     93:        .nevents = sizeof(intel_arch1_names) /
                     94:            sizeof(struct name_to_event),
                     95:        .next = NULL
                     96: };
                     97:
                     98: static struct event_table *
                     99: init_intel_arch1(void)
                    100: {
                    101:        unsigned int eax, ebx, ecx, edx;
                    102:        struct event_table *table;
                    103:        size_t i;
                    104:
                    105:        eax = 0x0A;
                    106:        ebx = 0;
                    107:        ecx = 0;
                    108:        edx = 0;
                    109:        x86_cpuid(&eax, &ebx, &ecx, &edx);
                    110:
                    111:        table = &intel_arch1;
                    112:        for (i = 0; i < table->nevents; i++) {
                    113:                /* Disable the unsupported events. */
                    114:                if ((ebx & (i << 1)) != 0)
                    115:                        table->names[i].enabled = false;
                    116:        }
                    117:
                    118:        return table;
                    119: }
                    120:
                    121: /*
1.5       knakahar  122:  * Intel Silvermont/Airmont.
                    123:  */
                    124: static struct name_to_event intel_silvermont_airmont_names[] = {
                    125:        { "REHABQ.LD_BLOCK_ST_FORWARD",         0x03, 0x01, true },
                    126:        { "REHABQ.LD_BLOCK_STD_NOTREADY",       0x03, 0x02, true },
                    127:        { "REHABQ.ST_SPLITS",                   0x03, 0x04, true },
                    128:        { "REHABQ.LD_SPLITS",                   0x03, 0x08, true },
                    129:        { "REHABQ.LOCK",                        0x03, 0x10, true },
                    130:        { "REHABQ.STA_FULL",                    0x03, 0x20, true },
                    131:        { "REHABQ.ANY_LD",                      0x03, 0x40, true },
                    132:        { "REHABQ.ANY_ST",                      0x03, 0x80, true },
                    133:        { "MEM_UOPS_RETIRED.L1_MISS_LOADS",     0x04, 0x01, true },
                    134:        { "MEM_UOPS_RETIRED.L2_HIT_LOADS",      0x04, 0x02, true },
                    135:        { "MEM_UOPS_RETIRED.L2_MISS_LOADS",     0x04, 0x04, true },
                    136:        { "MEM_UOPS_RETIRED.DTLB_MISS_LOADS",   0x04, 0x08, true },
                    137:        { "MEM_UOPS_RETIRED.UTLB_MISS",         0x04, 0x10, true },
                    138:        { "MEM_UOPS_RETIRED.HITM",              0x04, 0x20, true },
                    139:        { "MEM_UOPS_RETIRED.ALL_LOADS",         0x04, 0x40, true },
                    140:        { "MEM_UOP_RETIRED.ALL_STORES",         0x04, 0x80, true },
                    141:        { "PAGE_WALKS.D_SIDE_CYCLES",           0x05, 0x01, true },
                    142:        { "PAGE_WALKS.I_SIDE_CYCLES",           0x05, 0x02, true },
                    143:        { "PAGE_WALKS.WALKS",                   0x05, 0x03, true },
                    144:        { "LONGEST_LAT_CACHE.MISS",             0x2E, 0x41, true },
                    145:        { "LONGEST_LAT_CACHE.REFERENCE",        0x2E, 0x4F, true },
                    146:        { "L2_REJECT_XQ.ALL",                   0x30, 0x00, true },
                    147:        { "CORE_REJECT_L2Q.ALL",                0x31, 0x00, true },
                    148:        { "CPU_CLK_UNHALTED.CORE_P",            0x3C, 0x00, true },
                    149:        { "CPU_CLK_UNHALTED.REF_P",             0x3C, 0x01, true },
                    150:        { "ICACHE.HIT",                         0x80, 0x01, true },
                    151:        { "ICACHE.MISSES",                      0x80, 0x02, true },
                    152:        { "ICACHE.ACCESSES",                    0x80, 0x03, true },
                    153:        { "OFFCORE_RESPONSE_0",                 0xB7, 0x01, true },
                    154:        { "OFFCORE_RESPONSE_1",                 0xB7, 0x02, true },
                    155:        { "INST_RETIRED.ANY_P",                 0xC0, 0x00, true },
                    156:        { "UOPS_RETIRED.MS",                    0xC2, 0x01, true },
                    157:        { "UOPS_RETIRED.ALL",                   0xC2, 0x10, true },
                    158:        { "MACHINE_CLEARS.SMC",                 0xC3, 0x01, true },
                    159:        { "MACHINE_CLEARS.MEMORY_ORDERING",     0xC3, 0x02, true },
                    160:        { "MACHINE_CLEARS.FP_ASSIST",           0xC3, 0x04, true },
                    161:        { "MACHINE_CLEARS.ALL",                 0xC3, 0x08, true },
                    162:        { "BR_INST_RETIRED.ALL_BRANCHES",       0xC4, 0x00, true },
                    163:        { "BR_INST_RETIRED.JCC",                0xC4, 0x7E, true },
                    164:        { "BR_INST_RETIRED.FAR_BRANCH",         0xC4, 0xBF, true },
                    165:        { "BR_INST_RETIRED.NON_RETURN_IND",     0xC4, 0xEB, true },
                    166:        { "BR_INST_RETIRED.RETURN",             0xC4, 0xF7, true },
                    167:        { "BR_INST_RETIRED.CALL",               0xC4, 0xF9, true },
                    168:        { "BR_INST_RETIRED.IND_CALL",           0xC4, 0xFB, true },
                    169:        { "BR_INST_RETIRED.REL_CALL",           0xC4, 0xFD, true },
                    170:        { "BR_INST_RETIRED.TAKEN_JCC",          0xC4, 0xFE, true },
                    171:        { "BR_MISP_RETIRED.ALL_BRANCHES",       0xC5, 0x00, true },
                    172:        { "BR_MISP_RETIRED.JCC",                0xC5, 0x7E, true },
                    173:        { "BR_MISP_RETIRED.FAR",                0xC5, 0xBF, true },
                    174:        { "BR_MISP_RETIRED.NON_RETURN_IND",     0xC5, 0xEB, true },
                    175:        { "BR_MISP_RETIRED.RETURN",             0xC5, 0xF7, true },
                    176:        { "BR_MISP_RETIRED.CALL",               0xC5, 0xF9, true },
                    177:        { "BR_MISP_RETIRED.IND_CALL",           0xC5, 0xFB, true },
                    178:        { "BR_MISP_RETIRED.REL_CALL",           0xC5, 0xFD, true },
                    179:        { "BR_MISP_RETIRED.TAKEN_JCC",          0xC5, 0xFE, true },
                    180:        { "NO_ALLOC_CYCLES.ROB_FULL",           0xCA, 0x01, true },
                    181:        { "NO_ALLOC_CYCLES.RAT_STALL",          0xCA, 0x20, true },
                    182:        { "NO_ALLOC_CYCLES.ALL",                0xCA, 0x3F, true },
                    183:        { "NO_ALLOC_CYCLES.NOT_DELIVERED",      0xCA, 0x50, true },
                    184:        { "RS_FULL_STALL.MEC",                  0xCB, 0x01, true },
                    185:        { "RS_FULL_STALL.ALL",                  0xCB, 0x1F, true },
                    186:        { "CYCLES_DIV_BUSY.ANY",                0xCD, 0x01, true },
                    187:        { "BACLEARS.ALL",                       0xE6, 0x01, true },
                    188:        { "BACLEARS.RETURN",                    0xE6, 0x08, true },
                    189:        { "BACLEARS.COND",                      0xE6, 0x10, true },
                    190:        { "MS_DECODED.MS_ENTRY",                0xE7, 0x01, true },
                    191: };
                    192:
                    193: static struct event_table intel_silvermont_airmont = {
                    194:        .tablename = "Intel Silvermont/Airmont",
                    195:        .names = intel_silvermont_airmont_names,
                    196:        .nevents = sizeof(intel_silvermont_airmont_names) /
                    197:            sizeof(struct name_to_event),
                    198:        .next = NULL
                    199: };
                    200:
                    201: static struct event_table *
                    202: init_intel_silvermont_airmont(void)
                    203: {
                    204:
                    205:        return &intel_silvermont_airmont;
                    206: }
                    207:
                    208: /*
1.6       knakahar  209:  * Intel Goldmont
                    210:  */
                    211: static struct name_to_event intel_goldmont_names[] = {
                    212:        { "LD_BLOCKS.ALL_BLOCK",                        0x03,   0x10, true },
                    213:        { "LD_BLOCKS.UTLB_MISS",                        0x03,   0x08, true },
                    214:        { "LD_BLOCKS.STORE_FORWARD",                    0x03,   0x02, true },
                    215:        { "LD_BLOCKS.DATA_UNKNOWN",                     0x03,   0x01, true },
                    216:        { "LD_BLOCKS.4K_ALIAS",                         0x03,   0x04, true },
                    217:        { "PAGE_WALKS.D_SIDE_CYCLES",                   0x05,   0x01, true },
                    218:        { "PAGE_WALKS.I_SIDE_CYCLES",                   0x05,   0x02, true },
                    219:        { "PAGE_WALKS.CYCLES",                          0x05,   0x03, true },
                    220:        { "UOPS_ISSUED.ANY",                            0x0E,   0x00, true },
                    221:        { "MISALIGN_MEM_REF.LOAD_PAGE_SPLIT",           0x13,   0x02, true },
                    222:        { "MISALIGN_MEM_REF.STORE_PAGE_SPLIT",          0x13,   0x04, true },
                    223:        { "LONGEST_LAT_CACHE.REFERENCE",                0x2E,   0x4F, true },
                    224:        { "LONGEST_LAT_CACHE.MISS",                     0x2E,   0x41, true },
                    225:        { "L2_REJECT_XQ.ALL",                           0x30,   0x00, true },
                    226:        { "CORE_REJECT_L2Q.ALL",                        0x31,   0x00, true },
                    227:        { "CPU_CLK_UNHALTED.CORE_P",                    0x3C,   0x00, true },
                    228:        { "CPU_CLK_UNHALTED.REF",                       0x3C,   0x01, true },
                    229:        { "DL1.DIRTY_EVICTION",                         0x51,   0x01, true },
                    230:        { "ICACHE.HIT",                                 0x80,   0x01, true },
                    231:        { "ICACHE.MISSES",                              0x80,   0x02, true },
                    232:        { "ICACHE.ACCESSES",                            0x80,   0x03, true },
                    233:        { "ITLB.MISS",                                  0x81,   0x04, true },
                    234:        { "FETCH_STALL.ALL",                            0x86,   0x00, true },
                    235:        { "FETCH_STALL.ITLB_FILL_PENDING_CYCLES",       0x86,   0x01, true },
                    236:        { "FETCH_STALL.ICACHE_FILL_PENDING_CYCLES",     0x86,   0x02, true },
                    237:        { "UOPS_NOT_DELIVERED.ANY",                     0x9C,   0x00, true },
                    238:        { "OFFCORE_RESPONSE.0",                         0xB7,   0x01, true },
                    239:        { "OFFCORE_RESPONSE.1",                         0xB7,   0x02, true },
                    240:        { "INST_RETIRED.ANY_P",                         0xC0,   0x00, true },
                    241:        { "UOPS_RETIRED.ANY",                           0xC2,   0x00, true },
                    242:        { "UOPS_RETIRED.MS",                            0xC2,   0x01, true },
                    243:        { "UOPS_RETIRED.FPDIV",                         0xC2,   0x08, true },
                    244:        { "UOPS_RETIRED.IDIV",                          0xC2,   0x10, true },
                    245:        { "MACHINE_CLEARS.SMC",                         0xC3,   0x01, true },
                    246:        { "MACHINE_CLEARS.MEMORY_ORDERING",             0xC3,   0x02, true },
                    247:        { "MACHINE_CLEARS.FP_ASSIST",                   0xC3,   0x04, true },
                    248:        { "MACHINE_CLEARS.DISAMBIGUATION",              0xC3,   0x08, true },
                    249:        { "MACHINE_CLEARS.ALL",                         0xC3,   0x00, true },
                    250:        { "BR_INST_RETIRED.ALL_BRANCHES",               0xC4,   0x00, true },
                    251:        { "BR_INST_RETIRED.JCC",                        0xC4,   0x7E, true },
                    252:        { "BR_INST_RETIRED.ALL_TAKEN_BRANCHES",         0xC4,   0x80, true },
                    253:        { "BR_INST_RETIRED.TAKEN_JCC",                  0xC4,   0xFE, true },
                    254:        { "BR_INST_RETIRED.CALL",                       0xC4,   0xF9, true },
                    255:        { "BR_INST_RETIRED.REL_CALL",                   0xC4,   0xFD, true },
                    256:        { "BR_INST_RETIRED.IND_CALL",                   0xC4,   0xFB, true },
                    257:        { "BR_INST_RETIRED.RETURN",                     0xC4,   0xF7, true },
                    258:        { "BR_INST_RETIRED.NON_RETURN_IND",             0xC4,   0xEB, true },
                    259:        { "BR_INST_RETIRED.FAR_BRANCH",                 0xC4,   0xBF, true },
                    260:        { "BR_MISP_RETIRED.ALL_BRANCHES",               0xC5,   0x00, true },
                    261:        { "BR_MISP_RETIRED.JCC",                        0xC5,   0x7E, true },
                    262:        { "BR_MISP_RETIRED.TAKEN_JCC",                  0xC5,   0xFE, true },
                    263:        { "BR_MISP_RETIRED.IND_CALL",                   0xC5,   0xFB, true },
                    264:        { "BR_MISP_RETIRED.RETURN",                     0xC5,   0xF7, true },
                    265:        { "BR_MISP_RETIRED.NON_RETURN_IND",             0xC5,   0xEB, true },
                    266:        { "ISSUE_SLOTS_NOT_CONSUMED.RESOURCE_FULL",     0xCA,   0x01, true },
                    267:        { "ISSUE_SLOTS_NOT_CONSUMED.RECOVERY",          0xCA,   0x02, true },
                    268:        { "ISSUE_SLOTS_NOT_CONSUMED.ANY",               0xCA,   0x00, true },
                    269:        { "HW_INTERRUPTS.RECEIVED",                     0xCB,   0x01, true },
                    270:        { "HW_INTERRUPTS.MASKED",                       0xCB,   0x02, true },
                    271:        { "HW_INTERRUPTS.PENDING_AND_MASKED",           0xCB,   0x04, true },
                    272:        { "CYCLES_DIV_BUSY.ALL",                        0xCD,   0x00, true },
                    273:        { "CYCLES_DIV_BUSY.IDIV",                       0xCD,   0x01, true },
                    274:        { "CYCLES_DIV_BUSY.FPDIV",                      0xCD,   0x02, true },
                    275:        { "MEM_UOPS_RETIRED.ALL_LOADS",                 0xD0,   0x81, true },
                    276:        { "MEM_UOPS_RETIRED.ALL_STORES",                0xD0,   0x82, true },
                    277:        { "MEM_UOPS_RETIRED.ALL",                       0xD0,   0x83, true },
                    278:        { "MEM_UOPS_RETIRED.DTLB_MISS_LOADS",           0xD0,   0x11, true },
                    279:        { "MEM_UOPS_RETIRED.DTLB_MISS_STORES",          0xD0,   0x12, true },
                    280:        { "MEM_UOPS_RETIRED.DTLB_MISS",                 0xD0,   0x13, true },
                    281:        { "MEM_UOPS_RETIRED.LOCK_LOADS",                0xD0,   0x21, true },
                    282:        { "MEM_UOPS_RETIRED.SPLIT_LOADS",               0xD0,   0x41, true },
                    283:        { "MEM_UOPS_RETIRED.SPLIT_STORES",              0xD0,   0x42, true },
                    284:        { "MEM_UOPS_RETIRED.SPLIT",                     0xD0,   0x43, true },
                    285:        { "MEM_LOAD_UOPS_RETIRED.L1_HIT",               0xD1,   0x01, true },
                    286:        { "MEM_LOAD_UOPS_RETIRED.L1_MISS",              0xD1,   0x08, true },
                    287:        { "MEM_LOAD_UOPS_RETIRED.L2_HIT",               0xD1,   0x02, true },
                    288:        { "MEM_LOAD_UOPS_RETIRED.L2_MISS",              0xD1,   0x10, true },
                    289:        { "MEM_LOAD_UOPS_RETIRED.HITM",                 0xD1,   0x20, true },
                    290:        { "MEM_LOAD_UOPS_RETIRED.WCB_HIT",              0xD1,   0x40, true },
                    291:        { "MEM_LOAD_UOPS_RETIRED.DRAM_HIT",             0xD1,   0x80, true },
                    292:        { "BACLEARS.ALL",                               0xE6,   0x01, true },
                    293:        { "BACLEARS.RETURN",                            0xE6,   0x08, true },
                    294:        { "BACLEAR.CONDS",                              0xE6,   0x10, true },
                    295:        { "MS_DECODED.MS_ENTRY",                        0xE7,   0x01, true },
                    296:        { "DECODED_RESTRICTION.PREDECODE_WRONG",        0xE9,   0x01, true },
                    297: };
                    298:
                    299: static struct event_table intel_goldmont = {
                    300:        .tablename = "Intel Goldmont",
                    301:        .names = intel_goldmont_names,
                    302:        .nevents = sizeof(intel_goldmont_names) /
                    303:            sizeof(struct name_to_event),
                    304:        .next = NULL
                    305: };
                    306:
                    307: static struct event_table *
                    308: init_intel_goldmont(void)
                    309: {
                    310:
                    311:        return &intel_goldmont;
                    312: }
                    313:
                    314: /*
1.7     ! knakahar  315:  * Intel Goldmont Plus (Additions from Goldmont)
        !           316:  */
        !           317: static struct name_to_event intel_goldmontplus_names[] = {
        !           318:        { "INST_RETIRED.ANY",                           0x00,   0x01, true },
        !           319:        { "DTLB_LOAD_MISSES.WALK_COMPLETED_4K",         0x08,   0x02, true },
        !           320:        { "DTLB_LOAD_MISSES.WALK_COMPLETED_2M_4M",      0x08,   0x04, true },
        !           321:        { "DTLB_LOAD_MISSES.WALK_COMPLETED_1GB",        0x08,   0x08, true },
        !           322:        { "DTLB_LOAD_MISSES.WALK_PENDING",              0x08,   0x10, true },
        !           323:        { "DTLB_STORE_MISSES.WALK_COMPLETED_4K",        0x49,   0x02, true },
        !           324:        { "DTLB_STORE_MISSES.WALK_COMPLETED_2M_4M",     0x49,   0x04, true },
        !           325:        { "DTLB_STORE_MISSES.WALK_COMPLETED_1GB",       0x49,   0x08, true },
        !           326:        { "DTLB_STORE_MISSES.WALK_PENDING",             0x49,   0x10, true },
        !           327:        { "EPT.WALK_PENDING",                           0x4F,   0x10, true },
        !           328:        { "ITLB_MISSES.WALK_COMPLETED_4K",              0x85,   0x08, true },
        !           329:        { "ITLB_MISSES.WALK_COMPLETED_2M_4M",           0x85,   0x04, true },
        !           330:        { "ITLB_MISSES.WALK_COMPLETED_1GB",             0x85,   0x08, true },
        !           331:        { "ITLB_MISSES.WALK_PENDING",                   0x85,   0x10, true },
        !           332:        { "TLB_FLUSHES.STLB_ANY",                       0xBD,   0x20, true },
        !           333:        { "MACHINE_CLEARS.PAGE_FAULT",                  0xC3,   0x20, true },
        !           334: };
        !           335:
        !           336: static struct event_table intel_goldmontplus = {
        !           337:        .tablename = "Intel Goldmont Plus",
        !           338:        .names = intel_goldmontplus_names,
        !           339:        .nevents = sizeof(intel_goldmontplus_names) /
        !           340:            sizeof(struct name_to_event),
        !           341:        .next = NULL
        !           342: };
        !           343:
        !           344: static struct event_table *
        !           345: init_intel_goldmontplus(void)
        !           346: {
        !           347:
        !           348:        intel_goldmont.next = &intel_goldmontplus;
        !           349:
        !           350:        return &intel_goldmont;
        !           351: }
        !           352:
        !           353: /*
1.4       maxv      354:  * Intel Skylake/Kabylake.
                    355:  *
                    356:  * The events that are not listed, because they are of little interest or
                    357:  * require extra configuration:
                    358:  *     TX_*
                    359:  *     FRONTEND_RETIRED.*
                    360:  *     FP_ARITH_INST_RETIRED.*
                    361:  *     HLE_RETIRED.*
                    362:  *     RTM_RETIRED.*
                    363:  *     MEM_TRANS_RETIRED.*
                    364:  *     UOPS_DISPATCHED_PORT.*
1.1       maxv      365:  */
                    366: static struct name_to_event intel_skylake_kabylake_names[] = {
                    367:        /* Event Name - Event Select - UMask */
1.4       maxv      368:        { "LD_BLOCKS.STORE_FORWARD",                                    0x03, 0x02, true },
                    369:        { "LD_BLOCKS.NO_SR",                                            0x03, 0x08, true },
                    370:        { "LD_BLOCKS_PARTIAL.ADDRESS_ALIAS",                            0x07, 0x01, true },
                    371:        { "DTLB_LOAD_MISSES.MISS_CAUSES_A_WALK",                        0x08, 0x01, true },
                    372:        { "DTLB_LOAD_MISSES.WALK_COMPLETED_4K",                         0x08, 0x02, true },
                    373:        { "DTLB_LOAD_MISSES.WALK_COMPLETED_2M_4M",                      0x08, 0x04, true },
                    374:        { "DTLB_LOAD_MISSES.WALK_COMPLETED_1G",                         0x08, 0x08, true },
                    375:        { "DTLB_LOAD_MISSES.WALK_COMPLETED",                            0x08, 0x0E, true },
                    376:        { "DTLB_LOAD_MISSES.WALK_PENDING",                              0x08, 0x10, true },
                    377:        { "DTLB_LOAD_MISSES.STLB_HIT",                                  0x08, 0x20, true },
                    378:        { "INT_MISC.RECOVERY_CYCLES",                                   0x0D, 0x01, true },
                    379:        { "INT_MISC.CLEAR_RESTEER_CYCLES",                              0x0D, 0x80, true },
                    380:        { "UOPS_ISSUED.ANY",                                            0x0E, 0x01, true },
                    381:        { "UOPS_ISSUED.VECTOR_WIDTH_MISMATCH",                          0x0E, 0x02, true },
                    382:        { "UOPS_ISSUED.SLOW_LEA",                                       0x0E, 0x20, true },
                    383:        { "L2_RQSTS.DEMAND_DATA_RD_MISS",                               0x24, 0x21, true },
                    384:        { "L2_RQSTS.RFO_MISS",                                          0x24, 0x22, true },
                    385:        { "L2_RQSTS.CODE_RD_MISS",                                      0x24, 0x24, true },
                    386:        { "L2_RQSTS.ALL_DEMAND_MISS",                                   0x24, 0x27, true },
                    387:        { "L2_RQSTS.PF_MISS",                                           0x24, 0x38, true },
                    388:        { "L2_RQSTS.MISS",                                              0x24, 0x3F, true },
                    389:        { "L2_RQSTS.DEMAND_DATA_RD_HIT",                                0x24, 0x41, true },
                    390:        { "L2_RQSTS.RFO_HIT",                                           0x24, 0x42, true },
                    391:        { "L2_RQSTS.CODE_RD_HIT",                                       0x24, 0x44, true },
                    392:        { "L2_RQSTS.PF_HIT",                                            0x24, 0xD8, true },
                    393:        { "L2_RQSTS.ALL_DEMAND_DATA_RD",                                0x24, 0xE1, true },
                    394:        { "L2_RQSTS.ALL_RFO",                                           0x24, 0xE2, true },
                    395:        { "L2_RQSTS.ALL_CODE_RD",                                       0x24, 0xE4, true },
                    396:        { "L2_RQSTS.ALL_DEMAND_REFERENCES",                             0x24, 0xE7, true },
                    397:        { "L2_RQSTS.ALL_PF",                                            0x24, 0xF8, true },
                    398:        { "L2_RQSTS.REFERENCES",                                        0x24, 0xFF, true },
                    399:        { "SW_PREFETCH_ACCESS.NTA",                                     0x32, 0x01, true },
                    400:        { "SW_PREFETCH_ACCESS.T0",                                      0x32, 0x02, true },
                    401:        { "SW_PREFETCH_ACCESS.T1_T2",                                   0x32, 0x04, true },
                    402:        { "SW_PREFETCH_ACCESS.PREFETCHW",                               0x32, 0x08, true },
                    403:        { "CPU_CLK_THREAD_UNHALTED.ONE_THREAD_ACTIVE",                  0x3C, 0x02, true },
                    404:        { "CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE",                         0x3C, 0x02, true },
                    405:        { "L1D_PEND_MISS.PENDING",                                      0x48, 0x01, true },
                    406:        { "L1D_PEND_MISS.FB_FULL",                                      0x48, 0x02, true },
                    407:        { "DTLB_STORE_MISSES.MISS_CAUSES_A_WALK",                       0x49, 0x01, true },
                    408:        { "DTLB_STORE_MISSES.WALK_COMPLETED_4K",                        0x49, 0x02, true },
                    409:        { "DTLB_STORE_MISSES.WALK_COMPLETED_2M_4M",                     0x49, 0x04, true },
                    410:        { "DTLB_STORE_MISSES.WALK_COMPLETED_1G",                        0x49, 0x08, true },
                    411:        { "DTLB_STORE_MISSES.WALK_COMPLETED",                           0x49, 0x0E, true },
                    412:        { "DTLB_STORE_MISSES.WALK_PENDING",                             0x49, 0x10, true },
                    413:        { "DTLB_STORE_MISSES.STLB_HIT",                                 0x49, 0x20, true },
                    414:        { "LOAD_HIT_PRE.SW_PF",                                         0x4C, 0x01, true },
                    415:        { "EPT.WALK_PENDING",                                           0x4F, 0x10, true },
                    416:        { "L1D.REPLACEMENT",                                            0x51, 0x01, true },
                    417:        { "RS_EVENTS.EMPTY_CYCLES",                                     0x5E, 0x01, true },
                    418:        { "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_DATA_RD",                0x60, 0x01, true },
                    419:        { "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_CODE_RD",                0x60, 0x02, true },
                    420:        { "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_RFO",                    0x60, 0x04, true },
                    421:        { "OFFCORE_REQUESTS_OUTSTANDING.ALL_DATA_RD",                   0x60, 0x08, true },
                    422:        { "OFFCORE_REQUESTS_OUTSTANDING.L3_MISS_DEMAND_DATA_RD",        0x60, 0x10, true },
                    423:        { "IDQ.MITE_UOPS",                                              0x79, 0x04, true },
                    424:        { "IDQ.DSB_UOPS",                                               0x79, 0x08, true },
                    425:        { "IDQ.MS_MITE_UOPS",                                           0x79, 0x20, true },
                    426:        { "IDQ.MS_UOPS",                                                0x79, 0x30, true },
                    427:        { "ICACHE_16B.IFDATA_STALL",                                    0x80, 0x04, true },
                    428:        { "ICACHE_64B.IFTAG_HIT",                                       0x83, 0x01, true },
                    429:        { "ICACHE_64B.IFTAG_MISS",                                      0x83, 0x02, true },
                    430:        { "ICACHE_64B.IFTAG_STALL",                                     0x83, 0x04, true },
                    431:        { "ITLB_MISSES.MISS_CAUSES_A_WALK",                             0x85, 0x01, true },
                    432:        { "ITLB_MISSES.WALK_COMPLETED_4K",                              0x85, 0x02, true },
                    433:        { "ITLB_MISSES.WALK_COMPLETED_2M_4M",                           0x85, 0x04, true },
                    434:        { "ITLB_MISSES.WALK_COMPLETED_1G",                              0x85, 0x08, true },
                    435:        { "ITLB_MISSES.WALK_COMPLETED",                                 0x85, 0x0E, true },
                    436:        { "ITLB_MISSES.WALK_PENDING",                                   0x85, 0x10, true },
                    437:        { "ITLB_MISSES.STLB_HIT",                                       0x85, 0x20, true },
                    438:        { "ILD_STALL.LCP",                                              0x87, 0x01, true },
                    439:        { "IDQ_UOPS_NOT_DELIVERED.CORE",                                0x9C, 0x01, true },
                    440:        { "RESOURCE_STALLS.ANY",                                        0xA2, 0x01, true },
                    441:        { "RESOURCE_STALLS.SB",                                         0xA2, 0x08, true },
                    442:        { "EXE_ACTIVITY.EXE_BOUND_0_PORTS",                             0xA6, 0x01, true },
                    443:        { "EXE_ACTIVITY.1_PORTS_UTIL",                                  0xA6, 0x02, true },
                    444:        { "EXE_ACTIVITY.2_PORTS_UTIL",                                  0xA6, 0x04, true },
                    445:        { "EXE_ACTIVITY.3_PORTS_UTIL",                                  0xA6, 0x08, true },
                    446:        { "EXE_ACTIVITY.4_PORTS_UTIL",                                  0xA6, 0x10, true },
                    447:        { "EXE_ACTIVITY.BOUND_ON_STORES",                               0xA6, 0x40, true },
                    448:        { "LSD.UOPS",                                                   0xA8, 0x01, true },
                    449:        { "DSB2MITE_SWITCHES.PENALTY_CYCLES",                           0xAB, 0x02, true },
                    450:        { "ITLB.ITLB_FLUSH",                                            0xAE, 0x01, true },
                    451:        { "OFFCORE_REQUESTS.DEMAND_DATA_RD",                            0xB0, 0x01, true },
                    452:        { "OFFCORE_REQUESTS.DEMAND_CODE_RD",                            0xB0, 0x02, true },
                    453:        { "OFFCORE_REQUESTS.DEMAND_RFO",                                0xB0, 0x04, true },
                    454:        { "OFFCORE_REQUESTS.ALL_DATA_RD",                               0xB0, 0x08, true },
                    455:        { "OFFCORE_REQUESTS.L3_MISS_DEMAND_DATA_RD",                    0xB0, 0x10, true },
                    456:        { "OFFCORE_REQUESTS.ALL_REQUESTS",                              0xB0, 0x80, true },
                    457:        { "UOPS_EXECUTED.THREAD",                                       0xB1, 0x01, true },
                    458:        { "UOPS_EXECUTED.CORE",                                         0xB1, 0x02, true },
                    459:        { "UOPS_EXECUTED.X87",                                          0xB1, 0x10, true },
                    460:        { "OFFCORE_REQUESTS_BUFFER.SQ_FULL",                            0xB2, 0x01, true },
                    461:        { "TLB_FLUSH.DTLB_THREAD",                                      0xBD, 0x01, true },
                    462:        { "TLB_FLUSH.STLB_ANY",                                         0xBD, 0x20, true },
                    463:        { "INST_RETIRED.PREC_DIST",                                     0xC0, 0x01, true },
                    464:        { "OTHER_ASSISTS.ANY",                                          0xC1, 0x3F, true },
                    465:        { "UOPS_RETIRED.RETIRE_SLOTS",                                  0xC2, 0x02, true },
                    466:        { "MACHINE_CLEARS.MEMORY_ORDERING",                             0xC3, 0x02, true },
                    467:        { "MACHINE_CLEARS.SMC",                                         0xC3, 0x04, true },
                    468:        { "BR_INST_RETIRED.CONDITIONAL",                                0xC4, 0x01, true },
                    469:        { "BR_INST_RETIRED.NEAR_CALL",                                  0xC4, 0x02, true },
                    470:        { "BR_INST_RETIRED.NEAR_RETURN",                                0xC4, 0x08, true },
                    471:        { "BR_INST_RETIRED.NOT_TAKEN",                                  0xC4, 0x10, true },
                    472:        { "BR_INST_RETIRED.NEAR_TAKEN",                                 0xC4, 0x20, true },
                    473:        { "BR_INST_RETIRED.FAR_BRANCH",                                 0xC4, 0x40, true },
                    474:        { "BR_MISP_RETIRED.CONDITIONAL",                                0xC5, 0x01, true },
                    475:        { "BR_MISP_RETIRED.NEAR_CALL",                                  0xC5, 0x02, true },
                    476:        { "BR_MISP_RETIRED.NEAR_TAKEN",                                 0xC5, 0x20, true },
                    477:        { "HW_INTERRUPTS.RECEIVED",                                     0xCB, 0x01, true },
                    478:        { "MEM_INST_RETIRED.STLB_MISS_LOADS",                           0xD0, 0x11, true },
                    479:        { "MEM_INST_RETIRED.STLB_MISS_STORES",                          0xD0, 0x12, true },
                    480:        { "MEM_INST_RETIRED.LOCK_LOADS",                                0xD0, 0x21, true },
                    481:        { "MEM_INST_RETIRED.SPLIT_LOADS",                               0xD0, 0x41, true },
                    482:        { "MEM_INST_RETIRED.SPLIT_STORES",                              0xD0, 0x42, true },
                    483:        { "MEM_INST_RETIRED.ALL_LOADS",                                 0xD0, 0x81, true },
                    484:        { "MEM_INST_RETIRED.ALL_STORES",                                0xD0, 0x82, true },
                    485:        { "MEM_LOAD_RETIRED.L1_HIT",                                    0xD1, 0x01, true },
                    486:        { "MEM_LOAD_RETIRED.L2_HIT",                                    0xD1, 0x02, true },
                    487:        { "MEM_LOAD_RETIRED.L3_HIT",                                    0xD1, 0x04, true },
                    488:        { "MEM_LOAD_RETIRED.L1_MISS",                                   0xD1, 0x08, true },
                    489:        { "MEM_LOAD_RETIRED.L2_MISS",                                   0xD1, 0x10, true },
                    490:        { "MEM_LOAD_RETIRED.L3_MISS",                                   0xD1, 0x20, true },
                    491:        { "MEM_LOAD_RETIRED.FB_HIT",                                    0xD1, 0x40, true },
                    492:        { "MEM_LOAD_L3_HIT_RETIRED.XSNP_MISS",                          0xD2, 0x01, true },
                    493:        { "MEM_LOAD_L3_HIT_RETIRED.XSNP_HIT",                           0xD2, 0x02, true },
                    494:        { "MEM_LOAD_L3_HIT_RETIRED.XSNP_HITM",                          0xD2, 0x04, true },
                    495:        { "MEM_LOAD_L3_HIT_RETIRED.XSNP_NONE",                          0xD2, 0x08, true },
                    496:        { "MEM_LOAD_MISC_RETIRED.UC",                                   0xD4, 0x04, true },
                    497:        { "BACLEARS.ANY",                                               0xE6, 0x01, true },
                    498:        { "L2_TRANS.L2_WB",                                             0xF0, 0x40, true },
                    499:        { "L2_LINES_IN.ALL",                                            0xF1, 0x1F, true },
                    500:        { "L2_LINES_OUT.SILENT",                                        0xF2, 0x01, true },
                    501:        { "L2_LINES_OUT.NON_SILENT",                                    0xF2, 0x02, true },
                    502:        { "L2_LINES_OUT.USELESS_HWPF",                                  0xF2, 0x04, true },
                    503:        { "SQ_MISC.SPLIT_LOCK",                                         0xF4, 0x10, true },
1.1       maxv      504: };
                    505:
                    506: static struct event_table intel_skylake_kabylake = {
                    507:        .tablename = "Intel Skylake/Kabylake",
                    508:        .names = intel_skylake_kabylake_names,
                    509:        .nevents = sizeof(intel_skylake_kabylake_names) /
                    510:            sizeof(struct name_to_event),
                    511:        .next = NULL
                    512: };
                    513:
                    514: static struct event_table *
                    515: init_intel_skylake_kabylake(void)
                    516: {
                    517:        return &intel_skylake_kabylake;
                    518: }
                    519:
                    520: static struct event_table *
                    521: init_intel_generic(void)
                    522: {
                    523:        unsigned int eax, ebx, ecx, edx;
                    524:        struct event_table *table;
                    525:
                    526:        /*
                    527:         * The kernel made sure the Architectural Version 1 PMCs were
                    528:         * present.
                    529:         */
                    530:        table = init_intel_arch1();
                    531:
                    532:        /*
                    533:         * Now query the additional (non-architectural) events. They
                    534:         * depend on the CPU model.
                    535:         */
                    536:        eax = 0x01;
                    537:        ebx = 0;
                    538:        ecx = 0;
                    539:        edx = 0;
                    540:        x86_cpuid(&eax, &ebx, &ecx, &edx);
                    541:
1.3       maxv      542:        if (CPUID_TO_FAMILY(eax) == 6) {
                    543:                switch (CPUID_TO_MODEL(eax)) {
1.5       knakahar  544:                case 0x37: /* Silvermont (Bay Trail) */
                    545:                case 0x4A: /* Silvermont (Tangier) */
                    546:                case 0x4C: /* Airmont (Braswell, Cherry Trail) */
                    547:                case 0x4D: /* Silvermont (Avoton, Rangeley) */
                    548:                case 0x5A: /* Silvermont (Anniedale) */
                    549:                case 0x5D: /* Silvermont (SoFIA) */
                    550:                        table->next = init_intel_silvermont_airmont();
                    551:                        break;
1.6       knakahar  552:                case 0x5C: /* Goldmont (Apollo Lake) */
                    553:                case 0x5F: /* Goldmont (Denvertion) */
                    554:                        table->next = init_intel_goldmont();
                    555:                        break;
1.7     ! knakahar  556:                case 0x7A: /* Goldmont Plus (Gemini Lake) */
        !           557:                        table->next = init_intel_goldmontplus();
        !           558:                        break;
1.3       maxv      559:                case 0x4E: /* Skylake */
                    560:                case 0x5E: /* Skylake */
                    561:                case 0x8E: /* Kabylake */
                    562:                case 0x9E: /* Kabylake */
                    563:                        table->next = init_intel_skylake_kabylake();
                    564:                        break;
                    565:                }
1.1       maxv      566:        }
                    567:
                    568:        return table;
                    569: }
                    570:
                    571: /* -------------------------------------------------------------------------- */
                    572:
                    573: /*
                    574:  * AMD Family 10h
                    575:  */
                    576: static struct name_to_event amd_f10h_names[] = {
1.2       maxv      577:        { "seg-load-all",               0x20, 0x7f, true },
                    578:        { "seg-load-es",                0x20, 0x01, true },
                    579:        { "seg-load-cs",                0x20, 0x02, true },
                    580:        { "seg-load-ss",                0x20, 0x04, true },
                    581:        { "seg-load-ds",                0x20, 0x08, true },
                    582:        { "seg-load-fs",                0x20, 0x10, true },
                    583:        { "seg-load-gs",                0x20, 0x20, true },
                    584:        { "seg-load-hs",                0x20, 0x40, true },
                    585:        { "l1cache-access",             0x40, 0x00, true },
                    586:        { "l1cache-miss",               0x41, 0x00, true },
                    587:        { "l1cache-refill",             0x42, 0x1f, true },
                    588:        { "l1cache-refill-invalid",     0x42, 0x01, true },
                    589:        { "l1cache-refill-shared",      0x42, 0x02, true },
                    590:        { "l1cache-refill-exclusive",   0x42, 0x04, true },
                    591:        { "l1cache-refill-owner",       0x42, 0x08, true },
                    592:        { "l1cache-refill-modified",    0x42, 0x10, true },
                    593:        { "l1cache-load",               0x43, 0x1f, true },
                    594:        { "l1cache-load-invalid",       0x43, 0x01, true },
                    595:        { "l1cache-load-shared",        0x43, 0x02, true },
                    596:        { "l1cache-load-exclusive",     0x43, 0x04, true },
                    597:        { "l1cache-load-owner",         0x43, 0x08, true },
                    598:        { "l1cache-load-modified",      0x43, 0x10, true },
                    599:        { "l1cache-writeback",          0x44, 0x1f, true },
                    600:        { "l1cache-writeback-invalid",  0x44, 0x01, true },
                    601:        { "l1cache-writeback-shared",   0x44, 0x02, true },
                    602:        { "l1cache-writeback-exclusive",0x44, 0x04, true },
                    603:        { "l1cache-writeback-owner",    0x44, 0x08, true },
                    604:        { "l1cache-writeback-modified", 0x44, 0x10, true },
                    605:        { "l1DTLB-hit-all",             0x4D, 0x07, true },
                    606:        { "l1DTLB-hit-4Kpage",          0x4D, 0x01, true },
                    607:        { "l1DTLB-hit-2Mpage",          0x4D, 0x02, true },
                    608:        { "l1DTLB-hit-1Gpage",          0x4D, 0x04, true },
                    609:        { "l1DTLB-miss-all",            0x45, 0x07, true },
                    610:        { "l1DTLB-miss-4Kpage",         0x45, 0x01, true },
                    611:        { "l1DTLB-miss-2Mpage",         0x45, 0x02, true },
                    612:        { "l1DTLB-miss-1Gpage",         0x45, 0x04, true },
                    613:        { "l2DTLB-miss-all",            0x46, 0x03, true },
                    614:        { "l2DTLB-miss-4Kpage",         0x46, 0x01, true },
                    615:        { "l2DTLB-miss-2Mpage",         0x46, 0x02, true },
1.1       maxv      616:        /* l2DTLB-miss-1Gpage: reserved on some revisions, so disabled */
1.2       maxv      617:        { "l1ITLB-miss",                0x84, 0x00, true },
                    618:        { "l2ITLB-miss-all",            0x85, 0x03, true },
                    619:        { "l2ITLB-miss-4Kpage",         0x85, 0x01, true },
                    620:        { "l2ITLB-miss-2Mpage",         0x85, 0x02, true },
                    621:        { "mem-misalign-ref",           0x47, 0x00, true },
                    622:        { "ins-fetch",                  0x80, 0x00, true },
                    623:        { "ins-fetch-miss",             0x81, 0x00, true },
                    624:        { "ins-refill-l2",              0x82, 0x00, true },
                    625:        { "ins-refill-sys",             0x83, 0x00, true },
                    626:        { "ins-fetch-stall",            0x87, 0x00, true },
                    627:        { "ins-retired",                0xC0, 0x00, true },
                    628:        { "ins-empty",                  0xD0, 0x00, true },
                    629:        { "ops-retired",                0xC1, 0x00, true },
                    630:        { "branch-retired",             0xC2, 0x00, true },
                    631:        { "branch-miss-retired",        0xC3, 0x00, true },
                    632:        { "branch-taken-retired",       0xC4, 0x00, true },
                    633:        { "branch-taken-miss-retired",  0xC5, 0x00, true },
                    634:        { "branch-far-retired",         0xC6, 0x00, true },
                    635:        { "branch-resync-retired",      0xC7, 0x00, true },
                    636:        { "branch-near-retired",        0xC8, 0x00, true },
                    637:        { "branch-near-miss-retired",   0xC9, 0x00, true },
                    638:        { "branch-indirect-miss-retired", 0xCA, 0x00, true },
                    639:        { "int-hw",                     0xCF, 0x00, true },
                    640:        { "int-cycles-masked",          0xCD, 0x00, true },
                    641:        { "int-cycles-masked-pending",  0xCE, 0x00, true },
                    642:        { "fpu-exceptions",             0xDB, 0x00, true },
                    643:        { "break-match0",               0xDC, 0x00, true },
                    644:        { "break-match1",               0xDD, 0x00, true },
                    645:        { "break-match2",               0xDE, 0x00, true },
                    646:        { "break-match3",               0xDF, 0x00, true },
1.1       maxv      647: };
                    648:
                    649: static struct event_table amd_f10h = {
                    650:        .tablename = "AMD Family 10h",
                    651:        .names = amd_f10h_names,
                    652:        .nevents = sizeof(amd_f10h_names) /
                    653:            sizeof(struct name_to_event),
                    654:        .next = NULL
                    655: };
                    656:
                    657: static struct event_table *
                    658: init_amd_f10h(void)
                    659: {
                    660:        return &amd_f10h;
                    661: }
                    662:
                    663: static struct event_table *
                    664: init_amd_generic(void)
                    665: {
                    666:        unsigned int eax, ebx, ecx, edx;
                    667:
                    668:        eax = 0x01;
                    669:        ebx = 0;
                    670:        ecx = 0;
                    671:        edx = 0;
                    672:        x86_cpuid(&eax, &ebx, &ecx, &edx);
                    673:
                    674:        switch (CPUID_TO_FAMILY(eax)) {
                    675:        case 0x10:
                    676:                return init_amd_f10h();
                    677:        }
                    678:
                    679:        return NULL;
                    680: }
                    681:
                    682: /* -------------------------------------------------------------------------- */
                    683:
                    684: int
                    685: tprof_event_init(uint32_t ident)
                    686: {
                    687:        switch (ident) {
                    688:        case TPROF_IDENT_NONE:
                    689:                return -1;
                    690:        case TPROF_IDENT_INTEL_GENERIC:
                    691:                cpuevents = init_intel_generic();
                    692:                break;
                    693:        case TPROF_IDENT_AMD_GENERIC:
                    694:                cpuevents = init_amd_generic();
                    695:                break;
                    696:        }
                    697:        return (cpuevents == NULL) ? -1 : 0;
                    698: }
                    699:
                    700: static void
                    701: recursive_event_list(struct event_table *table)
                    702: {
                    703:        size_t i;
                    704:
                    705:        printf("%s:\n", table->tablename);
                    706:        for (i = 0; i < table->nevents; i++) {
                    707:                if (!table->names[i].enabled)
                    708:                        continue;
                    709:                printf("\t%s\n", table->names[i].name);
                    710:        }
                    711:
                    712:        if (table->next != NULL) {
                    713:                recursive_event_list(table->next);
                    714:        }
                    715: }
                    716:
                    717: void
                    718: tprof_event_list(void)
                    719: {
                    720:        recursive_event_list(cpuevents);
                    721: }
                    722:
                    723: static void
                    724: recursive_event_lookup(struct event_table *table, const char *name,
                    725:     struct tprof_param *param)
                    726: {
                    727:        size_t i;
                    728:
                    729:        for (i = 0; i < table->nevents; i++) {
                    730:                if (!table->names[i].enabled)
                    731:                        continue;
                    732:                if (!strcmp(table->names[i].name, name)) {
                    733:                        param->p_event = table->names[i].event;
                    734:                        param->p_unit = table->names[i].unit;
                    735:                        return;
                    736:                }
                    737:        }
                    738:
                    739:        if (table->next != NULL) {
                    740:                recursive_event_lookup(table->next, name, param);
                    741:        } else {
                    742:                errx(EXIT_FAILURE, "event '%s' unknown", name);
                    743:        }
                    744: }
                    745:
                    746: void
                    747: tprof_event_lookup(const char *name, struct tprof_param *param)
                    748: {
                    749:        recursive_event_lookup(cpuevents, name, param);
                    750: }

CVSweb <webmaster@jp.NetBSD.org>