Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
894e823
feat(axcpu): MIDR ClusterId classifier + PMU clean-slate helpers
JosephJoshua Jun 26, 2026
026c870
feat(starry): per-core PMU bring-up + cached cluster identity
JosephJoshua Jun 26, 2026
2161cbe
feat(starry): per-CPU PMU pools + per-slice counter allocation
JosephJoshua Jun 27, 2026
d6061f6
test(starry): smp4 perf per-CPU migration + no-exhaustion tests
JosephJoshua Jun 27, 2026
d46d140
feat(starry): perf stat -a per-CPU fan-out + per-core PMCR.E
JosephJoshua Jun 28, 2026
cb20a05
test(starry): smp4 perf stat -a per-CPU fan-out test
JosephJoshua Jun 28, 2026
ea0e01e
feat(axtask): nullable per-CPU perf-tick hook in timer path
JosephJoshua Jun 28, 2026
32ae054
feat(starry): Tier-2 PMU counter rotation (multiplexing)
JosephJoshua Jun 28, 2026
ea7c869
test(starry): smp4 Tier-2 counter multiplexing test
JosephJoshua Jun 28, 2026
7ef2f1f
feat(starry): big.LITTLE cluster-aware perf programming + branch-even…
JosephJoshua Jun 28, 2026
dfb8fe4
feat(starry): dual-cluster sysfs PMUs armv8_cortex_a55/a76
JosephJoshua Jun 28, 2026
5bf7ec1
test(starry): smp4 big.LITTLE cluster-skip + dual-PMU test
JosephJoshua Jun 28, 2026
0ab9cb6
fix(starry): perf review fixes — slice accounting, exit-lock, rotation
JosephJoshua Jun 28, 2026
eb55ced
test(starry): reset perf_test_force_clusters on cluster-test exit
JosephJoshua Jun 28, 2026
b21bd83
fix(starry): pin self/system-wide perf event HW lifecycle to home core
JosephJoshua Jun 28, 2026
43f29a2
test(starry): smp4 home-core IPI test (cpu<0 event, migrated monitor)
JosephJoshua Jun 28, 2026
aadf96c
test(starry): RK3588 big.LITTLE perf board-validation suite
JosephJoshua Jun 28, 2026
4fec3cc
fix(starry): map perf mmap pages cacheable for hardware coherency
JosephJoshua Jul 2, 2026
6442276
test(starry): fix perf-validate cap_user_rdpmc bitfield offset
JosephJoshua Jul 2, 2026
4118265
test(starry): perf-validate board deploy path + mechanics (validated …
JosephJoshua Jul 2, 2026
1dad3d4
test(starry): smp8 multi-core validated on board; fix BR-7/IPC-1 arti…
JosephJoshua Jul 2, 2026
e40476d
test(starry): relocate perf SMP tests into the consolidated qemu/ group
JosephJoshua Jul 8, 2026
b9bbf6d
test(starry): raise perf-validate board timeout to 900s
JosephJoshua Jul 10, 2026
5db663a
feat(starry): perf PERF_FORMAT_LOST + ring lost-sample accounting
JosephJoshua Jul 10, 2026
89142dd
test(starry): on-target perf smoke case + pinned build recipe
JosephJoshua Jul 10, 2026
392f0dc
test(starry): libelf perf build recipe (user-symbol names)
JosephJoshua Jul 10, 2026
cf76774
fix(starry): gate perf-validate qemu case to aarch64
JosephJoshua Jul 11, 2026
b5a3664
fix(starry): skip perf-hw-smp-* qemu cases on non-aarch64
JosephJoshua Jul 11, 2026
738b771
test(perf): make perf-tool-smoke deterministic + propagate failures
JosephJoshua Jul 14, 2026
0187f5c
ci(perf): automate perf-validate board provisioning + fail fast when …
JosephJoshua Jul 14, 2026
2855759
fix(perf-validate): sync after board deploy so StarryOS sees the binary
JosephJoshua Jul 14, 2026
193c3ff
ci(perf): drop broken board auto-deploy; pre-stage perf-validate out-…
JosephJoshua Jul 14, 2026
c529468
test(perf-tool-smoke): gate the aarch64 perf asset to aarch64; verify…
JosephJoshua Jul 14, 2026
9be9d9f
test(perf-validate): split a FULL-only smp8 big.LITTLE board case
JosephJoshua Jul 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions components/axcpu/src/aarch64/pmu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,51 @@ pub fn read_midr_el1() -> u64 {
value
}

/// Which CPU cluster (microarchitecture) a core belongs to, decoded from
/// `MIDR_EL1`. RK3588 is big.LITTLE: Cortex-A76 "big" + Cortex-A55 "LITTLE".
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ClusterId {
/// Cortex-A55 ("LITTLE"), `MIDR_EL1` partnum `0xD05`.
Little,
/// Cortex-A76 ("big"), `MIDR_EL1` partnum `0xD0B`.
Big,
/// Any other implementation (e.g. QEMU `virt`'s Cortex-A53 `0xD03`); the
/// raw partnum is carried for diagnostics.
Other(u16),
}

/// `MIDR_EL1.Implementer` value for Arm Limited.
const MIDR_IMPLEMENTER_ARM: u64 = 0x41;
/// `MIDR_EL1.PartNum` for Cortex-A55.
const MIDR_PARTNUM_CORTEX_A55: u64 = 0xD05;
/// `MIDR_EL1.PartNum` for Cortex-A76.
const MIDR_PARTNUM_CORTEX_A76: u64 = 0xD0B;

/// Classify a raw `MIDR_EL1` value into a [`ClusterId`].
///
/// Mirrors Linux's `MIDR_CPU_MODEL_MASK` comparison (implementer + partnum;
/// variant/revision excluded). Pure so it is host-unit-testable.
pub fn classify_midr(midr: u64) -> ClusterId {
let implementer = (midr >> 24) & 0xff;
let partnum = (midr >> 4) & 0xfff;
if implementer != MIDR_IMPLEMENTER_ARM {
return ClusterId::Other(partnum as u16);
}
match partnum {
MIDR_PARTNUM_CORTEX_A55 => ClusterId::Little,
MIDR_PARTNUM_CORTEX_A76 => ClusterId::Big,
other => ClusterId::Other(other as u16),
}
}

/// Classify the current core into a [`ClusterId`] from `MIDR_EL1`.
///
/// Must be called *on* the core being classified — `MIDR_EL1` reflects only the
/// executing PE.
pub fn cluster_id() -> ClusterId {
classify_midr(read_midr_el1())
}

/// Self-check guarding against firmware / `MDCR_EL2` issues that keep the cycle
/// counter frozen.
///
Expand Down Expand Up @@ -476,6 +521,16 @@ pub mod counter {
}
}

/// Disables every counter at once (`PMCNTENCLR_EL0 = 0xFFFF_FFFF`), the
/// programmable counters and the cycle counter (bit 31). Used by the
/// per-core clean-slate bring-up so a freshly-entered secondary core starts
/// with nothing counting.
pub fn disable_all() {
unsafe {
asm!("msr PMCNTENCLR_EL0, {}", in(reg) 0xFFFF_FFFFu64);
}
}

/// Resets counter `n` (`PMEVCNTRn_EL0 = 0`).
///
/// Out-of-range `n` is a no-op (debug builds assert).
Expand Down Expand Up @@ -592,6 +647,24 @@ pub mod overflow {
asm!("msr PMINTENCLR_EL1, {}", in(reg) 1u64 << n);
}
}

/// Masks the overflow interrupt for every counter
/// (`PMINTENCLR_EL1 = 0xFFFF_FFFF`). Used by the per-core clean-slate
/// bring-up so a freshly-entered secondary core has no overflow IRQ armed.
pub fn disable_all_irq() {
unsafe {
asm!("msr PMINTENCLR_EL1, {}", in(reg) 0xFFFF_FFFFu64);
}
}

/// Clears every overflow-status flag (`PMOVSCLR_EL0 = 0xFFFF_FFFF`,
/// write-1-to-clear). Used by the per-core clean-slate bring-up so a stale
/// overflow flag cannot raise a spurious PMU interrupt.
pub fn clear_all() {
unsafe {
asm!("msr PMOVSCLR_EL0, {}", in(reg) 0xFFFF_FFFFu64);
}
}
}

/// The interrupted program counter (`ELR_EL1`).
Expand Down
4 changes: 2 additions & 2 deletions os/StarryOS/kernel/src/perf/bpf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const BPF_JIT_MEM_PAGES: usize = 4;
/// `mmap(perf_fd)`; None before).
///
/// Ownership model: the user VMA owns the ringbuf pages via the strong
/// `Arc<GlobalPage>` threaded into `DeviceMmap::Physical`'s retainer slot;
/// `Arc<GlobalPage>` threaded into `DeviceMmap::PhysicalCached`'s retainer slot;
/// this wrapper keeps only a `Weak`. Consequences:
///
/// * UAF safety — the pages outlive `close(perf_fd)` (which drops this
Expand Down Expand Up @@ -202,7 +202,7 @@ impl PerfEventOps for BpfPerfEventWrapper {
}
let pages = Arc::new(pages);
// Keep only a `Weak`; hand the sole strong ref to the caller, which
// threads it into `DeviceMmap::Physical`'s retainer so the user VMA
// threads it into `DeviceMmap::PhysicalCached`'s retainer so the user VMA
// pins these frames until `munmap`/exit even if the perf fd (and this
// wrapper) is closed first. Because the wrapper does not retain a
// strong ref, an mmap that is abandoned or fails before a VMA adopts
Expand Down
Loading
Loading