FABRIC-3.10.8 MC-1b: aarch64's second core online and parked
Cores from the DTB /cpus or, on QEMU (ACPI, no DTB), the MADT GICC entries; the MADT lookup is now shared (hal/acpi.c) with amd64. PSCI CPU_ON through the discovered conduit into ap_entry.S, which copies the boot core's MMU/control state, sets TPIDR_EL1 and parks. Core 1 online at EL1 with its own block; its vCPU thread 0.0% on the host. QEMU aarch64 -smp 2 -name debug-threads=on. 3-ISA acceptance clean. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
24bde47481
commit
3a2ba5149f
@@ -874,3 +874,44 @@ The ledger reads pulled 319488 / returned 316703 on all three. That is the K-3 b
|
||||
- **Not as named in advance:** the host-side check (core 1's vCPU thread near 0% in `ps -L`) could not be made. QEMU names its threads per vCPU only with `-name debug-threads=on`, which is not on the command line. The park-wake counter (0 wakes) is the evidence of record. Adding `-name debug-threads=on` is a candidate for MC-1b's run line.
|
||||
|
||||
**MC-1a is complete.** amd64 now boots two cores, and the second is parked with interrupts masked. Next: MC-1b (aarch64, PSCI `CPU_ON`).
|
||||
|
||||
### 5.2 MC-1b — aarch64's second core online and parked (2026-09-26)
|
||||
|
||||
**Go:** Captain Bob, 2026-09-26, *"keep going"*.
|
||||
|
||||
**Change.**
|
||||
- **Enumeration** (`arch/aarch64/smp.c`): the devicetree's `/cpus` children with `device_type = "cpu"` (their `reg`, per `#address-cells`) when the firmware hands one over, as on the RPi5. Otherwise, the ACPI MADT's enabled GICC entries (type 0x0B, MPIDR at +68).
|
||||
- QEMU's AAVMF hands over ACPI and no DTB (`PSCI: no DTB -- using HVC`), so on QEMU the cores come from the MADT.
|
||||
- The hardware id is the MPIDR affinity (Aff3..Aff0). The boot core's is read from `MPIDR_EL1`.
|
||||
- **The MADT lookup is now shared** (`hal/acpi.c`, `acpi_find_table()`). amd64's own copy in `arch/amd64/smp.c` is removed and uses it.
|
||||
- **Start:** PSCI `CPU_ON` (SMC64 0xC4000003) through the conduit `arch.c` already discovers (`aarch64_psci_cpu_on()`; HVC on QEMU). Entry is `ap_entry.S`, with x0 = the core's boot block, heap-allocated and kept.
|
||||
- The block, the core's per-core block, and the first 256 bytes of the entry code are cleaned to the point of coherency (`dc cvac`, `dsb sy`) before the call, because the core starts with its MMU and caches off. TCG does not model this; the RPi5 will.
|
||||
- A non-zero PSCI return is printed and the start refused.
|
||||
- **`ap_entry.S`:**
|
||||
- It masks DAIF and copies the boot core's MAIR, TCR, TTBR0/1, VBAR and CPACR (FP/SIMD on). Then it does `tlbi vmalle1` and `ic iallu`, and writes SCTLR, which turns the MMU and caches on at the same identity-mapped address.
|
||||
- It sets TPIDR_EL1 to its block, loads its stack, records CurrentEL in its boot block, and calls `sk_smp_secondary_main()`.
|
||||
- It references no symbol: every address comes from the block, because the file is also assembled for the PE/COFF loader.
|
||||
- **Park:** `msr daifset, #0xf` and `wfi`, each wake counted.
|
||||
- **`arch_smp_arrival()`** is a per-ISA phrase in the online line: "EL1" on aarch64 (from the recorded CurrentEL), "long mode" on amd64.
|
||||
- **QEMU:** `-smp 2 -name debug-threads=on` on the `make qemu` aarch64 line only. The thread names make the host-side check possible.
|
||||
|
||||
**Evidence** (clean builds; the source diff is identical to the saved stage diff):
|
||||
|
||||
| ISA | log | SMP lines | standard sequence |
|
||||
|---|---|---|---|
|
||||
| aarch64 (`-smp 2`) | `logs/20260926-124518` | `SMP: 2 core(s) found`; `SMP: core 1 online: hw id 0x1, block 0x0000000048000130, per-CPU register 0x0000000048000130 (its own block), EL1, 226 us, parked`; `SMP: 2 core(s) online` | K-10 hashes, G A=40 B=40 byte-identical, HHH, all ok `3`, ledger unchanged, 0 B idle, 0 / 0; **0 park-wake lines, 0 `LOCK:` lines** |
|
||||
| amd64 (`-smp 2`) | `logs/20260926-125631` | as MC-1a, now with "long mode": `core 1 online: hw id 0x1, ... (its own block), long mode, 500 us, parked` | same; 0 park wakes, 0 `LOCK:` |
|
||||
| riscv64 | `logs/20260926-130637` | 1 core found, 1 online | same |
|
||||
|
||||
**Host side, aarch64** (`ps -L` on the QEMU process after O-A, then 20 s later):
|
||||
|
||||
| thread | %CPU | CPU time | 20 s later |
|
||||
|---|---|---|---|
|
||||
| `CPU 0/TCG` | 63.5 | 5:10 | 63.8, 5:24 |
|
||||
| `CPU 1/TCG` | **0.0** | **0:00** | **0.0, 0:00** |
|
||||
|
||||
Core 1 is halted, not spinning.
|
||||
|
||||
**Found, not changed:** core 0's vCPU burns about 64% of a host CPU while the system is idle. The boot core's idle loop (the console poll and idle point) polls rather than halting. This predates MC-1. MC-3's criterion "idle worker cores halted, not spinning" applies to the new cores; whether core 0 should halt when idle too is a separate question for MC-3's design.
|
||||
|
||||
**MC-1b is complete.** Next: MC-1c (riscv64, SBI HSM `hart_start`).
|
||||
|
||||
Reference in New Issue
Block a user