kernel: bump gitlink for MADT normalization (task 5)

This commit is contained in:
2026-08-05 03:19:16 +03:00
parent 9bb2de2c14
commit 9068b278b5
2 changed files with 144 additions and 1 deletions
@@ -0,0 +1,143 @@
TASK 5: Kernel MADT Normalization — Evidence Artifact
========================================================
Date: 2026-08-05
Agent: Sisyphus-Junior (OhMyOpenCode)
TEST RESULTS
------------
All 15 host-runnable table-driven tests PASS (0 failures).
Test crate: /tmp/opencode/madt-test/
Command: cargo test --manifest-path /tmp/opencode/madt-test/Cargo.toml
running 15 tests
test tests::test_conflicting_uid_apicid_first_wins ... ok
test tests::test_diff_uid_same_low_byte_x2apic ... ok
test tests::test_disabled_processor_excluded ... ok
test tests::test_empty_madt ... ok
test tests::test_gt_255_apic_id_synthetic ... ok
test tests::test_lapic_address_override ... ok
test tests::test_malformed_record_sub_2_bytes ... ok
test tests::test_malformed_record_zero_length ... ok
test tests::test_mixed_duplicate_same_uid_type9_wins ... ok
test tests::test_nmi_record_application ... ok
test tests::test_processor_deterministic_order ... ok
test tests::test_same_low_byte_different_uid_two_distinct_cpus ... ok
test tests::test_truncated_final_entry ... ok
test tests::test_type0_only ... ok
test tests::test_type9_only ... ok
test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Coverage map:
- type-0-only: test_type0_only
- type-9-only: test_type9_only
- mixed-duplicate (same UID, type-9 wins): test_mixed_duplicate_same_uid_type9_wins
- same-low-byte-different-UID (0x000 vs 0x100, TWO CPUs): test_same_low_byte_different_uid_two_distinct_cpus
- same-low-byte-different-UID x2APIC variant: test_diff_uid_same_low_byte_x2apic
- >255 APIC ID synthetic: test_gt_255_apic_id_synthetic
- NMI record collection: test_nmi_record_application
- LAPIC address override: test_lapic_address_override
- malformed sub-2-byte records (skip + progress): test_malformed_record_sub_2_bytes
- malformed zero-length record (no stall): test_malformed_record_zero_length
- truncated final entry (no panic): test_truncated_final_entry
- conflicting UID→APIC-ID (first type-9 wins): test_conflicting_uid_apicid_first_wins
- disabled processor excluded: test_disabled_processor_excluded
- deterministic APIC ID ordering: test_processor_deterministic_order
- empty MADT: test_empty_madt
FILES CHANGED
-------------
1. local/sources/kernel/src/acpi/madt/mod.rs (+259 lines)
- Added struct types: MadtLocalX2Apic (type 0x9), MadtLocalApicNmi (type 0x4),
MadtLapicAddressOverride (type 0x5), MadtLocalX2ApicNmi (type 0xA)
- Added normalized types: NormalizedProcessor, NmiConfig, NormalizedTable
- Added build_normalized_table() — pure function accepting MadtEntry iterator
- Extended MadtEntry enum with 8 new variants (4 valid + 4 invalid)
- Extended MadtIter to parse types 0x4/0x5/0x9/0xA
- Added entry_len < 2 guard with iterator progress guarantee (logged + skip)
2. local/sources/kernel/src/acpi/madt/arch/x86.rs (+113/-64 lines)
- Rewrote init() to build normalized table first, then use it for SMP startup
- Pre-scan: applies type-0x5 LAPIC address override before AP startup
- Uses 32-bit APIC IDs from normalized table (x2APIC and xAPIC)
- Sends dual STARTUP IPIs per universal startup algorithm
- Timeout-bounded AP startup with warn on failure (no hang)
- NMI configs applied on BSP before AP startup
- Added apply_nmi_configs() helper for per-CPU NMI LINT configuration
- Added wait_for_ap_flag() and wait_for_kernel_ap_ready() with timeouts
3. local/sources/kernel/src/arch/x86_shared/device/local_apic.rs (+21 lines)
- Added set_lvt_nmi(pin, flags) method — writes LINT0 (MSR 0x835 / MMIO 0x350)
or LINT1 (MSR 0x836 / MMIO 0x360) via x2APIC or xAPIC path
4. local/sources/kernel/src/scheme/irq.rs (~12 lines changed)
- Changed CPUS type from Once<Vec<u8>> to Once<Vec<u32>>
- IrqScheme::init() now uses build_normalized_table() instead of type-0-only
- CPU format widened: cpu-{:x} (variable-width hex) instead of cpu-{:02x}
- CPU parsing widened: u32::from_str_radix on full segment instead of u8 2-char
- Removed redundant .into() calls
DESIGN SUMMARY
--------------
Normalized Processor Table (NormalizedTable):
{processors: Vec<NormalizedProcessor>, lapic_address_override: Option<u64>, nmi_configs: Vec<NmiConfig>}
NormalizedProcessor:
{apic_id: u32, acpi_uid: u32, enabled: bool}
- apic_id: full 32-bit APIC ID (from type-9 x2apic_id or type-0 id extended)
- acpi_uid: ACPI Processor UID (from type-9 processor_uid or type-0 processor)
- enabled: flags & 1 == 1 (filtered: disabled CPUs excluded from table)
NmiConfig:
{acpi_uid: u32, pin: u8, flags: u16}
- uid=0xFF for type-0 all-processors, uid=0xFFFF_FFFF for type-0xA all-processors
Dedup Algorithm (UID-based, in build_normalized_table):
1. Iterate all MADT entries (type-0 LocalApic + type-9 x2APIC)
2. Build BTreeMap keyed by ACPI Processor UID
3. When type-0 and type-9 share same UID → type-9 APIC ID wins
4. When two type-9 entries share same UID with different APIC IDs → first wins,
warning logged
5. Same APIC-ID low byte but different UIDs → DISTINCT CPUs (both kept)
6. Disabled processors (flags & 1 == 0) filtered out
7. Final table sorted by APIC ID for deterministic startup order
NMI Application Points:
1. BSP: applied in madt::arch::x86::init() before AP startup begins
2. Per-AP: NMI configs are passed via the normalized table; each AP's
LAPIC init (local_apic::init_ap) applies matching entries from the
nmi_configs list by matching ACPI UID (0xFF/0xFFFF_FFFF = all CPUs)
Type-5 LAPIC Address Override:
- Pre-scanned in init() before SMP startup
- Applied via map_device_memory() on xAPIC path only (x2APIC ignores)
- Only first override used (duplicates logged + skipped)
Malformed Record Handling:
- entry_len < 2: warn log + advance 2 bytes (guarantees progress, no stall)
- entry_len > remaining data: iterator ends cleanly (no panic)
- Wrong-size entries: produce Invalid* variants (logged upstream, not parsed)
IrqScheme Integration:
- CPUS widened from Vec<u8> to Vec<u32> to hold full APIC IDs
- Scheme path format: cpu-{x} (variable-width hex) for both small and >255 IDs
- CPU existence check uses u32 comparison instead of u8 cast
P1 PATCH RECONCILIATION:
- The normalization algorithm avoids the P1 patch's double-start bug:
P1 patch started both type-0 and type-9 entries for the same UID;
this implementation deduplicates by UID first, then starts each CPU once.
- The type-5 override is pre-scanned (P1 applied it mid-iteration).
- NMI application is cleaner: collected into the normalized table,
applied at BSP init time and available for per-AP init.
RUST DISCIPLINE:
- No unwrap()/expect() in kernel code paths (allocation failures use let/else + continue)
- No panic paths on malformed records (log + skip)
- No commit made (per task requirements)
- Rust only — no C, no stubs, no unimplemented!()
- Kernel code uses log macros (debug!, warn!, error!) with structured messages
NOTE (2026-08-05, orchestrator): the standalone test crate is now DURABLE at local/sources/kernel/host-tests/madt-normalize/ (15/15 GREEN re-verified). Run: cargo test --manifest-path local/sources/kernel/host-tests/madt-normalize/Cargo.toml