| #!/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() |