Why: post-mortem debug, performance analysis, live system tracing, security audits.
03
Why MPAM Exists
Multi-tenant cloud: "noisy neighbour" VMs can thrash the LLC or saturate memory bandwidth, starving a better-paying tenant's SLA.
Mixed-criticality automotive: a safety-critical thread must not be affected by an infotainment workload running on other cores.
HPC: bin-packed workloads need cache + bandwidth isolation for reproducibility.
x86 has had the equivalent since 2016:
Intel CAT (Cache Allocation Technology)
Intel CDP (Code/Data Prioritisation)
Intel MBA (Memory Bandwidth Allocation)
Arm's answer: MPAM — Memory-system Partitioning and Monitoring, an architectural feature (Armv8.4-A onwards, mandatory in Neoverse N2+).
Partition ID (PartID)
Every memory-system transaction carries a PartID attribute (10-16 bit). Each MPAM-aware resource (cache, memory controller) has a configuration table indexed by PartID → capacity / bandwidth limits.
Additional tag: PMG
PartID tells the system what to do; PMG (Performance Monitoring Group) tells the system what to count. Typically paired but can be used independently.
04
MPAM Architecture
PartID carried in CHI/AXI user-sideband.
Every resource implements its own partition policy; discoverable via MPAM ID registers.
Each resource has:
Configuration arrays (indexed by PartID)
Monitoring counters (indexed by PartID or PMG)
Enable / disable bits
OS / hypervisor programs these via memory-mapped registers + MSR-like system regs (MPAM0/1/2/3_EL1/2/3).
05
MPAM Partitioning Controls
Control
What it limits
Typical resource
CPOR (Cache Portion Allocation)
Which L3 portions/slices can be filled by this partition
L2, L3, SLC
CMAX (Cache Max Allocation)
Max percentage of cache
Same
MBW_MIN / MBW_MAX
Guaranteed min / cap max memory BW
Memory controller
MBW_PBM (proportional)
Proportional-bandwidth scheme
Mem ctrl
MBWU
Counters for used BW per PartID
Mem ctrl
CSU
Counter of cache-space used per PartID
Each cache
The Linux resctrl interface abstracts all of these as "schemata" — L3:%d=mask;MB:%d=pct strings that users write to /sys/fs/resctrl/.
06
Linux Resctrl on MPAM
Linux kernel 5.19+ supports MPAM through the existing resctrl filesystem (originally built for Intel RDT/CAT).
Mount: mount -t resctrl resctrl /sys/fs/resctrl.
Inside the mount: one directory per partition, plus info/ showing capabilities (available PartIDs, resource caps).
Same API as x86 RDT. Portable to any MPAM-enabled Neoverse box. Kubernetes CRI-O and some OCI runtimes have hooks to set this up per container.
07
MPAM in Virtualization
Hypervisor at EL2 owns MPAM PartID allocation across VMs.
Guest sees a virtualised MPAM (MPAM1_EL1 / MPAMIDR_EL1). HCR_EL2 traps writes to these for policing.
KVM assigns a range of PartIDs to each guest; guest can sub-allocate internally (e.g., for resctrl inside the guest).
PartID Narrowing: hypervisor can narrow a guest's PartID space so guests can't set values outside their allotted range.
Cloud use: tenants request "gold" / "silver" / "bronze" SLA tiers → hypervisor assigns partition configs at VM start.
The noisy-neighbour fix
Before MPAM, a single ML-inference VM could fill the SLC and starve every other tenant on the socket. With MPAM the operator caps ML-inference to N% of SLC — SLAs predictable.
Automotive use
In a cockpit SoC: ASIL-D cluster gets guaranteed cache + bandwidth; infotainment gets what's left. MPAM enforces this in hardware even if infotainment goes berserk.
08
CoreSight — the System Debug Fabric
CoreSight (2004) is Arm's architectural debug + trace infrastructure. Evolved from earlier EmbeddedICE / ETMv1 / CCC.
Unifies every form of observability on an Arm SoC:
Program trace — ETM per core
Data trace — ETM data-watch, DWT on M-class
Debug access — DAP + APs
Event cross-triggering — CTI / CTM
System-level instrumentation — STM
Everything is discoverable at runtime via ROM tables in memory-mapped regions.
Used by JTAG probes (J-Link, ULINK), Linux perf, post-mortem dump tools, CTF tracers, and system-on-chip verification.
Class 0 vs Class 1
Class-0 CoreSight: integrated fabric, Arm-IP-based, ROM tables. Class-1: older / vendor-specific discovery via device tree or fixed table. Modern SoCs are nearly all Class-0.
Cortex-M version
Cortex-M has a simpler CoreSight — no ETM by default on M0, optional MTB on M0+, full ETM on M7/M33. Covered in the Cortex-M deck 06.
09
CoreSight Components
Component
Purpose
DAP (Debug Access Port)
Translates JTAG / SWD from the external probe into internal APB/AXI reads of registers
AP (Access Port)
Specific bus attached to DAP — MEM-AP for memory, APB-AP for config, JTAG-AP for legacy
ETM / ETMv4 / ETE
Per-core program + data trace — one per PE
ITM
Instrumentation Trace Macrocell — printf-like output from software
STM
System Trace Macrocell — peripherals + OS-level annotations
CTI
Cross Trigger Interface — trigger halt/resume/sample across cores + trace units
CTM
Cross Trigger Matrix — fabric connecting CTIs
Funnel
Merges trace streams from multiple sources
TMC (ETB / ETR / ETF)
Trace Memory Controller — buffers trace data in on-chip RAM or DRAM
TPIU
Trace Port Interface — streams trace out of a pad
STP / HSSTP
Higher-bandwidth trace output via SerDes
10
DAP — How Debug Access Works
External debugger (J-Link, DSTREAM, ULINK) connects via JTAG (TCK/TMS/TDI/TDO + TRSTn) or SWD (2-wire + clock).
Enters the SoC at the DAP. DAP translates debug commands into APB/AXI reads/writes on the SoC's internal debug fabric.
Multiple APs hang off the DAP:
MEM-AP — read/write any memory address (R/W as the CPU would see it)
Authentication: DAP can be locked in field (DBGEN / NIDEN / SPIDEN) — no debug without matching silicon-fused keys.
Secure-side debug separately gated via SPIDEN (Secure-Privileged Invasive Debug Enable).
Halt, step, poke
External debugger can halt a core, read registers via APB-AP → core's EDSCR/EDR registers, single-step via debug instructions. Same machinery that powers GDB's target remote.
OpenOCD / pyOCD
Open-source debuggers speak JTAG/SWD via USB adapters (CMSIS-DAP, FT2232H) and drive CoreSight via the same APs commercial tools use.
11
ETM — Program Trace
Each core has an ETM (Embedded Trace Macrocell) — snapshots every retired instruction + branch decision.
Output: compressed trace stream (PE-address every N branches + deltas).
Sinks options:
ETB / ETF — on-die SRAM (32 KB typical)
ETR — writes to DRAM (MiB-GiB, configurable)
TPIU — streams off-chip (limited by pad speed)
HSSTP — high-speed trace SerDes (multi-Gbps)
Versions: ETMv3 (classic), ETMv4 (most current Cortex-A), ETE (Armv9 — merges ETM with TRBE for non-invasive DRAM-backed trace).
// Enable ETM via Linux perf
$ perf record -e cs_etm/@tmc_etr0/u ./workload
# results in a .data file with raw ETM trace bytes
$ perf script # decodes to instruction-accurate
# PC history + branch decisions
# Alternatively:
$ /opt/ARM/DS/bin/trace_decode \
--snapshot /proc/kcore \
--etm-out trace.txt
The decode step is expensive but accurate: every retired instruction reconstructed. Used for post-crash analysis + finding rare races.
12
TRBE — Embedded Trace Buffer (Armv9)
Armv9-A / v8.6-A optional: TRBE — Trace Buffer Extension. Each core has a dedicated small trace buffer in its L2 tag area.
Trace gets written directly to DRAM via a page-size circular buffer — no separate CoreSight funnel needed.
Very low-overhead — the CPU manages its own trace buffer. Linux perf allocates DRAM pages and programs TRBPTR_EL1 / TRBBASER_EL1.
Mandatory in Neoverse N2+ (SBSA Level 6).
Use case: always-on instruction trace for flight-recorder-style post-mortem. If a production server crashes, last few million instructions are in DRAM, preserved across reboot if NVDIMM-backed.
TRBE for datacentre
Cloud operators (AWS, Azure) use TRBE to capture just-before-crash state for rare hypervisor bugs. Low enough overhead (~2-5%) to leave on in production fleets.
Related: BRBE
Branch Record Buffer Extension — a smaller, branch-history-only variant. Always-on last-N-branches buffer, very cheap. Used for profiling + security side-channel detection.
13
ITM & STM — Software Instrumentation
ITM (Instrumentation Trace Macrocell) — software writes to 32 stimulus ports. Each byte/halfword/word becomes a tagged trace packet.
Classic use: Cortex-M "printf over SWO" — ITM stimulus + TPIU + SWO pin = real-time debug console without a UART.
STM (System Trace Macrocell) — similar but system-wide: hundreds of channels, usable by any peripheral, interconnect node, or OS kernel.
Linux stm_ftrace driver writes kernel ftrace events to STM channels — synchronised with hardware trace for cross-layer debugging.
// Printf over ITM on Cortex-M (pre-ETM)
#define ITM_STIM(n) (*(volatile uint32_t*)(0xE0000000 + 4*(n)))
int itm_putchar(int ch) {
while ((ITM_STIM(0) & 1) == 0) ; // wait for FIFO
ITM_STIM(0) = ch;
return ch;
}
// Or Linux / Cortex-A kernel STM
#include <linux/stm.h>
stm_log(stm_info, "trace %d\n", x);
STM gives you ftrace-style kernel tracing synchronized with ETM program trace — timeline reconstruction across kernel events + every instruction executed.
14
CTI & Cross-Triggering
CTI (Cross Trigger Interface) — a per-component set of input/output trigger channels. Each core has one; so do the DAP, ETMs, CTIs.
CTM (Cross Trigger Matrix) — connects all CTIs into a broadcast fabric.
Allows: "when core 0 hits this breakpoint, halt all cores, start tracing on core 3, and pulse a debug GPIO."
Essential for debugging SMP bugs where cores need to be frozen synchronously — otherwise racy state changes while debugger is catching up.
Also used to trigger trace capture from a PMU-counter overflow: CPU counts L3 misses, at threshold CTI fires, trace starts.
CTI programming model
Each CTI has N (usually 8) inputs + N outputs. You program which input channels trigger which output channels — a small crossbar. OpenOCD abstracts this via arm_cti commands.
System-level idea
Think of CTI as an "interrupt fabric for debuggers" — it's the plumbing that makes GDB's thread apply all bt actually stop the whole SMP system atomically.
15
Lessons
"What does MPAM do?" → partitions cache + memory bandwidth per PartID so multi-tenant / mixed-criticality workloads can't interfere. Arm's answer to Intel CAT/MBA.
"What's a PartID?" → 10-16-bit identifier tagged to every memory-system transaction. MPAM-aware resources check it to enforce allocations + count usage.
"Linux resctrl on Arm?" → same /sys/fs/resctrl/ interface as Intel RDT, backed by MPAM. Write schemata like L3:0=ff;MB:0=50.
"CoreSight purpose?" → unified debug + trace fabric. DAP for debug access, ETM for program trace, ITM/STM for instrumentation, CTI for cross-triggering.
"How does an external debugger find every CoreSight component?" → ROM tables — discoverable memory regions listing base addresses + class IDs of every CoreSight IP on the SoC.
"ETM vs SPE?" → ETM captures every retired instruction (full trace, heavy). SPE statistically samples 1 in N instructions with latency + attribution (lighter, still actionable).
"What is TRBE?" → Armv9 Trace Buffer Extension: each core has its own DRAM-backed trace buffer. Low-overhead, suitable for always-on production flight recorder.
"Why CTI?" → without cross-triggering, debuggers can't halt an SMP system atomically. CTI makes "all cores halt on this break" a hardware-guaranteed event.