#!/usr/bin/python
|
#
|
# Copyright (C) 2015 The Android Open Source Project
|
#
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
# you may not use this file except in compliance with the License.
|
# You may obtain a copy of the License at
|
#
|
# http://www.apache.org/licenses/LICENSE-2.0
|
#
|
# Unless required by applicable law or agreed to in writing, software
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# See the License for the specific language governing permissions and
|
# limitations under the License.
|
#
|
|
|
def gen_event_type_entry_str(event_type_name, event_type, event_config, description='',
|
limited_arch=''):
|
"""
|
return string as below:
|
EVENT_TYPE_TABLE_ENTRY(event_type_name, event_type, event_config, description, limited_arch)
|
"""
|
return 'EVENT_TYPE_TABLE_ENTRY("%s", %s, %s, "%s", "%s")\n' % (
|
event_type_name, event_type, event_config, description, limited_arch)
|
|
def gen_arm_event_type_entry_str(event_type_name, event_type, event_config, description):
|
return gen_event_type_entry_str(event_type_name, event_type, event_config, description,
|
"arm")
|
|
|
def gen_hardware_events():
|
hardware_configs = ["cpu-cycles",
|
"instructions",
|
"cache-references",
|
"cache-misses",
|
"branch-instructions",
|
"branch-misses",
|
"bus-cycles",
|
"stalled-cycles-frontend",
|
"stalled-cycles-backend",
|
]
|
generated_str = ""
|
for config in hardware_configs:
|
event_type_name = config
|
event_config = "PERF_COUNT_HW_" + config.replace('-', '_').upper()
|
|
generated_str += gen_event_type_entry_str(
|
event_type_name, "PERF_TYPE_HARDWARE", event_config)
|
|
return generated_str
|
|
|
def gen_software_events():
|
software_configs = ["cpu-clock",
|
"task-clock",
|
"page-faults",
|
"context-switches",
|
"cpu-migrations",
|
["minor-faults", "PERF_COUNT_SW_PAGE_FAULTS_MIN"],
|
["major-faults", "PERF_COUNT_SW_PAGE_FAULTS_MAJ"],
|
"alignment-faults",
|
"emulation-faults",
|
]
|
generated_str = ""
|
for config in software_configs:
|
if isinstance(config, list):
|
event_type_name = config[0]
|
event_config = config[1]
|
else:
|
event_type_name = config
|
event_config = "PERF_COUNT_SW_" + config.replace('-', '_').upper()
|
|
generated_str += gen_event_type_entry_str(
|
event_type_name, "PERF_TYPE_SOFTWARE", event_config)
|
|
return generated_str
|
|
|
def gen_hw_cache_events():
|
hw_cache_types = [["L1-dcache", "PERF_COUNT_HW_CACHE_L1D"],
|
["L1-icache", "PERF_COUNT_HW_CACHE_L1I"],
|
["LLC", "PERF_COUNT_HW_CACHE_LL"],
|
["dTLB", "PERF_COUNT_HW_CACHE_DTLB"],
|
["iTLB", "PERF_COUNT_HW_CACHE_ITLB"],
|
["branch", "PERF_COUNT_HW_CACHE_BPU"],
|
["node", "PERF_COUNT_HW_CACHE_NODE"],
|
]
|
hw_cache_ops = [["loads", "load", "PERF_COUNT_HW_CACHE_OP_READ"],
|
["stores", "store", "PERF_COUNT_HW_CACHE_OP_WRITE"],
|
["prefetches", "prefetch",
|
"PERF_COUNT_HW_CACHE_OP_PREFETCH"],
|
]
|
hw_cache_op_results = [["accesses", "PERF_COUNT_HW_CACHE_RESULT_ACCESS"],
|
["misses", "PERF_COUNT_HW_CACHE_RESULT_MISS"],
|
]
|
generated_str = ""
|
for (type_name, type_config) in hw_cache_types:
|
for (op_name_access, op_name_miss, op_config) in hw_cache_ops:
|
for (result_name, result_config) in hw_cache_op_results:
|
if result_name == "accesses":
|
event_type_name = type_name + '-' + op_name_access
|
else:
|
event_type_name = type_name + '-' + \
|
op_name_miss + '-' + result_name
|
event_config = "((%s) | (%s << 8) | (%s << 16))" % (
|
type_config, op_config, result_config)
|
generated_str += gen_event_type_entry_str(
|
event_type_name, "PERF_TYPE_HW_CACHE", event_config)
|
|
return generated_str
|
|
def gen_user_space_events():
|
generated_str = gen_event_type_entry_str("inplace-sampler",
|
"SIMPLEPERF_TYPE_USER_SPACE_SAMPLERS",
|
"SIMPLEPERF_CONFIG_INPLACE_SAMPLER")
|
return generated_str
|
|
def gen_arm_raw_events():
|
# Refer to "Table D5-7 PMU event numbers" in ARMv8 specification.
|
raw_types = [
|
[0x00, "sw-incr", "software increment"],
|
[0x01, "l1-icache-refill", "level 1 instruction cache refill"],
|
[0x02, "l1-itlb-refill", "level 1 instruction TLB refill"],
|
[0x03, "l1-dcache-refill", "level 1 data cache refill"],
|
[0x04, "l1-dcache", "level 1 data cache access"],
|
[0x05, "l1-dtlb-refill", "level 1 data TLB refill"],
|
[0x06, "load-retired", "load (instruction architecturally executed)"],
|
[0x07, "store-retired", "store (instruction architecturally executed)"],
|
[0x08, "instruction-retired", "instructions (instruction architecturally executed)"],
|
[0x09, "exception-taken", "exception taken"],
|
[0x0a, "exception-return", "exception return (instruction architecturally executed)"],
|
[0x0b, "cid-write-retired", "write to CONTEXIDR (instruction architecturally executed)"],
|
[0x0c, "pc-write-retired", "software change of the PC (instruction architecturally executed)"],
|
[0x0d, "br-immed-retired", "immediate branch (instruction architecturally executed)"],
|
[0x0e, "br-return-retired", "procedure return (instruction architecturally executed)"],
|
[0x0f, "unaligned-ldst-retired", "unaligned load or store (instruction architecturally executed)"],
|
[0x10, "br-mis-pred", "mispredicted or not predicted branch speculatively executed"],
|
[0x11, "cpu-cycles", "cpu cycles"],
|
[0x12, "br-pred", "predictable branch speculatively executed"],
|
[0x13, "mem-access", "data memory access"],
|
[0x14, "l1-icache", "level 1 instruction cache access"],
|
[0x15, "l1-dcache-wb", "level 1 data cache write-back"],
|
[0x16, "l2-dcache", "level 2 data cache access"],
|
[0x17, "l2-dcache-refill", "level 2 data cache refill"],
|
[0x18, "l2-dcache-wb", "level 2 data cache write-back"],
|
[0x19, "bus-access", "bus access"],
|
[0x1a, "memory-error", "local memory error"],
|
[0x1b, "inst-spec", "operation speculatively executed"],
|
[0x1c, "ttbr-write-retired", "write to TTBR (instruction architecturally executed)"],
|
[0x1d, "bus-cycles", "bus cycle"],
|
# [0x1e, "chain", ""], // Not useful in user space.
|
[0x1f, "l1-dcache-allocate", "level 1 data cache allocation without refill"],
|
[0x20, "l2-dcache-allocate", "level 2 data cache allocation without refill"],
|
[0x21, "br-retired", "branch (instruction architecturally executed)"],
|
[0x22, "br-mis-pred-retired", "mispredicted branch (instruction architecturally executed)"],
|
[0x23, "stall-frontend", "no operation issued due to the frontend"],
|
[0x24, "stall-backend", "no operation issued due to the backend"],
|
[0x25, "l1-dtlb", "level 1 data or unified TLB access"],
|
[0x26, "l1-itlb", "level 1 instruction TLB access"],
|
[0x27, "l2-icache", "level 2 instruction cache access"],
|
[0x28, "l2-icache-refill", "level 2 instruction cache refill"],
|
[0x29, "l3-dcache-allocate", "level 3 data or unified cache allocation without refill"],
|
[0x2a, "l3-dcache-refill", "level 3 data or unified cache refill"],
|
[0x2b, "l3-dcache", "level 3 data or unified cache access"],
|
[0x2c, "l3-dcache-wb", "level 3 data or unified cache write-back"],
|
[0x2d, "l2-dtlb-refill", "level 2 data or unified TLB refill"],
|
[0x2e, "l2-itlb-refill", "level 2 instruction TLB refill"],
|
[0x2f, "l2-dtlb", "level 2 data or unified TLB access"],
|
[0x30, "l2-itlb", "level 2 instruction TLB access"],
|
]
|
generated_str = ""
|
for item in raw_types:
|
event_type = 'PERF_TYPE_RAW'
|
event_type_name = "raw-" + item[1]
|
event_config = '0x%x' % item[0]
|
description = item[2]
|
generated_str += gen_arm_event_type_entry_str(event_type_name, event_type, event_config,
|
description)
|
return generated_str
|
|
|
def gen_events():
|
generated_str = "// This file is auto-generated by generate-event_table.py.\n\n"
|
generated_str += gen_hardware_events() + '\n'
|
generated_str += gen_software_events() + '\n'
|
generated_str += gen_hw_cache_events() + '\n'
|
generated_str += gen_user_space_events() + '\n'
|
generated_str += gen_arm_raw_events() + '\n'
|
return generated_str
|
|
generated_str = gen_events()
|
fh = open('event_type_table.h', 'w')
|
fh.write(generated_str)
|
fh.close()
|