drivers/perf/apple_m1_cpu_pmu.c
Source file repositories/reference/linux-study-clean/drivers/perf/apple_m1_cpu_pmu.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/perf/apple_m1_cpu_pmu.c- Extension
.c- Size
- 20502 bytes
- Lines
- 706
- Domain
- Driver Families
- Bucket
- drivers/perf
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/of.hlinux/perf/arm_pmu.hlinux/perf/arm_pmuv3.hlinux/platform_device.hasm/apple_m1_pmu.hasm/irq_regs.hasm/perf_event.h
Detected Declarations
enum m1_pmu_eventsfunction m1_pmu_events_sysfs_showfunction m1_pmu_read_hw_counterfunction m1_pmu_write_hw_counterfunction __m1_pmu_enable_counterfunction m1_pmu_enable_counterfunction m1_pmu_disable_counterfunction __m1_pmu_enable_counter_interruptfunction m1_pmu_enable_counter_interruptfunction m1_pmu_disable_counter_interruptfunction __m1_pmu_configure_event_filterfunction __m1_pmu_configure_eventselfunction registerfunction m1_pmu_configure_counterfunction m1_pmu_enable_eventfunction m1_pmu_disable_eventfunction m1_pmu_handle_irqfunction for_each_set_bitfunction m1_pmu_read_counterfunction m1_pmu_write_counterfunction m1_pmu_get_event_idxfunction m1_pmu_clear_event_idxfunction __m1_pmu_set_modefunction m1_pmu_startfunction m1_pmu_stopfunction m1_pmu_map_eventfunction m2_pmu_map_eventfunction m1_pmu_map_pmuv3_eventfunction m1_pmu_init_pmceidfunction m1_pmu_resetfunction m1_pmu_set_event_filterfunction m1_pmu_initfunction m1_pmu_ice_initfunction m1_pmu_fire_initfunction m2_pmu_avalanche_initfunction m2_pmu_blizzard_initfunction m1_pmu_device_probe
Annotated Snippet
// SPDX-License-Identifier: GPL-2.0
/*
* CPU PMU driver for the Apple M1 and derivatives
*
* Copyright (C) 2021 Google LLC
*
* Author: Marc Zyngier <maz@kernel.org>
*
* Most of the information used in this driver was provided by the
* Asahi Linux project. The rest was experimentally discovered.
*/
#include <linux/of.h>
#include <linux/perf/arm_pmu.h>
#include <linux/perf/arm_pmuv3.h>
#include <linux/platform_device.h>
#include <asm/apple_m1_pmu.h>
#include <asm/irq_regs.h>
#include <asm/perf_event.h>
#define M1_PMU_NR_COUNTERS 10
#define M1_PMU_CFG_EVENT GENMASK(7, 0)
#define ANY_BUT_0_1 GENMASK(9, 2)
#define ONLY_2_TO_7 GENMASK(7, 2)
#define ONLY_2_4_6 (BIT(2) | BIT(4) | BIT(6))
#define ONLY_5_6_7 (BIT(5) | BIT(6) | BIT(7))
/*
* Description of the events we actually know about, as well as those with
* a specific counter affinity. Yes, this is a grand total of two known
* counters, and the rest is anybody's guess.
*
* Not all counters can count all events. Counters #0 and #1 are wired to
* count cycles and instructions respectively, and some events have
* bizarre mappings (every other counter, or even *one* counter). These
* restrictions equally apply to both P and E cores.
*
* It is worth noting that the PMUs attached to P and E cores are likely
* to be different because the underlying uarches are different. At the
* moment, we don't really need to distinguish between the two because we
* know next to nothing about the events themselves, and we already have
* per cpu-type PMU abstractions.
*
* If we eventually find out that the events are different across
* implementations, we'll have to introduce per cpu-type tables.
*/
enum m1_pmu_events {
M1_PMU_PERFCTR_RETIRE_UOP = 0x1,
M1_PMU_PERFCTR_CORE_ACTIVE_CYCLE = 0x2,
M1_PMU_PERFCTR_L1I_TLB_FILL = 0x4,
M1_PMU_PERFCTR_L1D_TLB_FILL = 0x5,
M1_PMU_PERFCTR_MMU_TABLE_WALK_INSTRUCTION = 0x7,
M1_PMU_PERFCTR_MMU_TABLE_WALK_DATA = 0x8,
M1_PMU_PERFCTR_L2_TLB_MISS_INSTRUCTION = 0xa,
M1_PMU_PERFCTR_L2_TLB_MISS_DATA = 0xb,
M1_PMU_PERFCTR_MMU_VIRTUAL_MEMORY_FAULT_NONSPEC = 0xd,
M1_PMU_PERFCTR_SCHEDULE_UOP = 0x52,
M1_PMU_PERFCTR_INTERRUPT_PENDING = 0x6c,
M1_PMU_PERFCTR_MAP_STALL_DISPATCH = 0x70,
M1_PMU_PERFCTR_MAP_REWIND = 0x75,
M1_PMU_PERFCTR_MAP_STALL = 0x76,
M1_PMU_PERFCTR_MAP_INT_UOP = 0x7c,
M1_PMU_PERFCTR_MAP_LDST_UOP = 0x7d,
M1_PMU_PERFCTR_MAP_SIMD_UOP = 0x7e,
M1_PMU_PERFCTR_FLUSH_RESTART_OTHER_NONSPEC = 0x84,
M1_PMU_PERFCTR_INST_ALL = 0x8c,
M1_PMU_PERFCTR_INST_BRANCH = 0x8d,
M1_PMU_PERFCTR_INST_BRANCH_CALL = 0x8e,
M1_PMU_PERFCTR_INST_BRANCH_RET = 0x8f,
M1_PMU_PERFCTR_INST_BRANCH_TAKEN = 0x90,
M1_PMU_PERFCTR_INST_BRANCH_INDIR = 0x93,
M1_PMU_PERFCTR_INST_BRANCH_COND = 0x94,
M1_PMU_PERFCTR_INST_INT_LD = 0x95,
M1_PMU_PERFCTR_INST_INT_ST = 0x96,
M1_PMU_PERFCTR_INST_INT_ALU = 0x97,
M1_PMU_PERFCTR_INST_SIMD_LD = 0x98,
M1_PMU_PERFCTR_INST_SIMD_ST = 0x99,
M1_PMU_PERFCTR_INST_SIMD_ALU = 0x9a,
M1_PMU_PERFCTR_INST_LDST = 0x9b,
M1_PMU_PERFCTR_INST_BARRIER = 0x9c,
M1_PMU_PERFCTR_UNKNOWN_9f = 0x9f,
M1_PMU_PERFCTR_L1D_TLB_ACCESS = 0xa0,
M1_PMU_PERFCTR_L1D_TLB_MISS = 0xa1,
M1_PMU_PERFCTR_L1D_CACHE_MISS_ST = 0xa2,
M1_PMU_PERFCTR_L1D_CACHE_MISS_LD = 0xa3,
M1_PMU_PERFCTR_LD_UNIT_UOP = 0xa6,
M1_PMU_PERFCTR_ST_UNIT_UOP = 0xa7,
Annotation
- Immediate include surface: `linux/of.h`, `linux/perf/arm_pmu.h`, `linux/perf/arm_pmuv3.h`, `linux/platform_device.h`, `asm/apple_m1_pmu.h`, `asm/irq_regs.h`, `asm/perf_event.h`.
- Detected declarations: `enum m1_pmu_events`, `function m1_pmu_events_sysfs_show`, `function m1_pmu_read_hw_counter`, `function m1_pmu_write_hw_counter`, `function __m1_pmu_enable_counter`, `function m1_pmu_enable_counter`, `function m1_pmu_disable_counter`, `function __m1_pmu_enable_counter_interrupt`, `function m1_pmu_enable_counter_interrupt`, `function m1_pmu_disable_counter_interrupt`.
- Atlas domain: Driver Families / drivers/perf.
- Implementation status: source implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.