Skip to content

ioc: power_on clears only the lines the IOC drives - #274

Merged
techomancer merged 1 commit into
techomancer:mainfrom
AlexanderNyr:ioc-power-on-owned-lines
Oct 22, 2026
Merged

techomancer merged 1 commit into
techomancer:mainfrom
AlexanderNyr:ioc-power-on-owned-lines

Conversation

@AlexanderNyr

Copy link
Copy Markdown
Contributor

ioc: power_on clears only the lines the IOC drives

Ioc::power_on stored 0 over the CPU's whole interrupt word. That word is shared: besides the IOC's IP2..IP6 it carries IP7, which the compare timer raises from the hptimer thread, and bit 63, the soft-reset request a device sets through CpuDevice::signal. A reset through the IOC (Machine::reset, a snapshot load or a rollback — all of them run power_on_devices) therefore also dropped a timer tick or a pending soft reset that landed while it ran, neither of which the IOC owns. The window is the gap between cpu.power_on(), which is entitled to clear the word, and ioc.power_on(), which is not.

The change

  • power_on clears exactly the five lines update_interrupts drives (fetch_and, not store), so a reset no longer touches IP7 or bit 63.
  • IOC_OWNED_LINES names that set once, with the ownership rule in its doc comment, so the reset path and the update path cannot drift apart.

Tests

  • Unit test: power_on_clears_only_the_cpu_lines_the_ioc_drives: with every bit of the word set, a reset leaves everything except IP2..IP6, and the test pins IOC_OWNED_LINES to exactly those five, so IP7 (the compare timer's) and bit 63 (a soft-reset request) can never be folded into it.
  • The test fails on main: assertion left == right failed: a reset clears the IOC's own lines and nothing else; left: 0, right: 0xffff_ffff_ffff_e7ff — the whole word went to zero.
  • cargo test --lib: 1092 passed, 0 failed, 19 ignored (1091 before the change, i.e. the new test is the only difference). One unused_mut warning from net/testnet.rs:1292 is pre-existing on main.
  • Booted NetBSD 10.0/sgimips on an Indy (R4400), headless, over the PROM's own TFTP path: the stock netbsd-INSTALL32_IP2x installation kernel served with --tftp-dir, then boot -f bootp()/netbsd from the Command Monitor, with an empty 512 MB SCSI disk and a CD-ROM attached. The kernel reports the R4400, its L1/L2 caches, ioc0 ... machine Indy (Guinness), wdsc0 ... WD33C93A, sq0 ... SGI Seeq 80c03, the emulated SGI, IRIS EMUL DISK and Sony, CDU-76S, and then starts sysinst (NetBSD-10.0 Install System). Log: netbsd-boot-fixed.log.
    • Same image on main: built without this change and booted the same way — same kernel banner, same device list, same installer (main-boot.log). This change is a no-op on the boot path.
    • A monitor reset — the Machine::reset path that runs power_on_devices, i.e. this function — leaves the CPU at 0xffffffffbfc00000, and the second TFTP boot reaches the installer again (netbsd-two-boots-and-reset.log).
  • Built and tested with the default feature set on Linux only; the release-feature (lightning,jitv2,gpujit,idle-pause,hostgl) leg and the macOS/Windows legs were not run here.

Fixes #264

The CPU's interrupt word is shared. Besides the IOC's IP2..IP6 it
carries IP7, which the compare timer raises from the hptimer thread,
and bit 63, the soft-reset request a device sets through
CpuDevice::signal. power_on stored 0 over the whole word, so a reset
through the IOC — Machine::reset, a snapshot load or a rollback, all
of which run power_on_devices — could drop a tick or a pending soft
reset that landed while it ran, neither of which the IOC owns.

Clear exactly the five lines update_interrupts drives, and keep that
set in one constant. Test: a word with every bit set comes back with
only IP2..IP6 cleared.

Fixes techomancer#264
@techomancer

Copy link
Copy Markdown
Owner

thanks!

@techomancer
techomancer merged commit 3a3caeb into techomancer:main Oct 22, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Ioc::power_on clears the CPU's whole interrupt word, including IP7 (CPU timer)

2 participants