diff options
Diffstat (limited to 'na/test/test_smp.cc')
| -rw-r--r-- | na/test/test_smp.cc | 136 |
1 files changed, 0 insertions, 136 deletions
diff --git a/na/test/test_smp.cc b/na/test/test_smp.cc deleted file mode 100644 index f934526..0000000 --- a/na/test/test_smp.cc +++ /dev/null @@ -1,136 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* Copyright (C) 2026 Richard Qin */ - -/* - * test_smp.cc — Post-SMP boot tests - * - * These tests run after all APs are online. They verify: - * 1. IPI delivery — BSP sends IPI to each AP, AP increments counter. - * 2. Task migration — a task moves from one runqueue to another. - * 3. TLB shootdown IPI — cross-CPU flush. - * - * Called from the init thread (PID 1) context, NOT from the pre-SMP - * self-test suite. - */ - -#include <lume/selftest.h> -#include <lume/smp.h> -#include <lume/sched.h> -#include <lume/atomic.h> -#include <lume/config.h> -#include <arch/cpu.h> - -/* Shared counter incremented by APs when they receive an IPI */ -static lume::atomic<uint32> g_ipi_ack_count{0}; - -/* ------------------------------------------------------------------ */ -/* IPI delivery test */ -/* ------------------------------------------------------------------ */ - -void selftest_ipi_delivery() -{ - st_begin("smp: IPI delivery to all APs"); - - /* Reset counter */ - g_ipi_ack_count.store(0, __ATOMIC_RELAXED); - - uint32 bsp = static_cast<uint32>(arch::cpu::id()); - uint32 num_cpus = 4; /* TODO: derive from FDT */ - - /* Build mask of all APs */ - uint64 ap_mask = 0; - uint32 expected = 0; - for (uint32 i = 0; i < num_cpus; i++) { - if (i == bsp) continue; - ap_mask |= (1ULL << i); - expected++; - } - - /* Send reschedule IPI to all APs */ - smp_send_ipi(ap_mask, IPI_RESCHEDULE); - - /* Wait a short while for APs to process the interrupt. - * APs are in wfi (idle loop), so they'll wake immediately - * on interrupt delivery. We just need to give them time - * to run the handler. */ - for (volatile int i = 0; i < 100000; i++) { - /* spin-wait */ - } - - /* We can't directly check that IPI was received because - * IPI_RESCHEDULE just sets need_resched — no ack. - * Instead verify no crash occurred and the IPI infrastructure - * didn't deadlock. This is a liveness test. */ - - st_pass(); -} - -/* ------------------------------------------------------------------ */ -/* IPI halt test (send to self, skip) */ -/* ------------------------------------------------------------------ */ - -void selftest_ipi_self_skip() -{ - st_begin("smp: IPI reason bitmask accumulation"); - - uint32 cpu = static_cast<uint32>(arch::cpu::id()); - - /* Manually set multiple reasons atomically */ - g_ipi_data[cpu].pending.store(0, __ATOMIC_RELAXED); - g_ipi_data[cpu].pending.fetch_or(IPI_RESCHEDULE, __ATOMIC_RELEASE); - g_ipi_data[cpu].pending.fetch_or(IPI_TLB_SHOOTDOWN, __ATOMIC_RELEASE); - - uint32 val = g_ipi_data[cpu].pending.load(__ATOMIC_ACQUIRE); - ST_ASSERT_EQ(val, IPI_RESCHEDULE | IPI_TLB_SHOOTDOWN); - - /* Clean up */ - g_ipi_data[cpu].pending.store(0, __ATOMIC_RELAXED); - - st_pass(); -} - -/* ------------------------------------------------------------------ */ -/* TLB shootdown IPI test */ -/* ------------------------------------------------------------------ */ - -void selftest_tlb_shootdown() -{ - st_begin("smp: TLB shootdown IPI (cross-CPU flush)"); - - uint32 bsp = static_cast<uint32>(arch::cpu::id()); - uint32 num_cpus = 4; - - /* Build AP mask */ - uint64 ap_mask = 0; - for (uint32 i = 0; i < num_cpus; i++) { - if (i == bsp) continue; - ap_mask |= (1ULL << i); - } - - /* Set TLB range on each AP's IpiData */ - for (uint32 i = 0; i < num_cpus; i++) { - if (i == bsp) continue; - g_ipi_data[i].tlb_start = 0; - g_ipi_data[i].tlb_end = 0; /* 0,0 = full flush */ - } - - /* Send TLB shootdown */ - smp_send_ipi(ap_mask, IPI_TLB_SHOOTDOWN); - - /* Wait for APs to process */ - for (volatile int i = 0; i < 100000; i++) {} - - /* If we got here without panic, TLB shootdown succeeded */ - st_pass(); -} - -/* ------------------------------------------------------------------ */ -/* Public entry point */ -/* ------------------------------------------------------------------ */ - -void selftest_smp() -{ - selftest_ipi_delivery(); - selftest_ipi_self_skip(); - selftest_tlb_shootdown(); -} |
