dedupe glow/spin, fix disk-image bugs, add ci chd-sync, bump deps - #85
Merged
Conversation
Dependency hygiene - glow: iris pinned 0.13 while eframe pulled 0.17, so both compiled into iris-gui. Bumped iris to 0.17 and adapted the call sites -- tex_image_2d takes PixelUnpackData now, and PixelUnpackData/PixelPackData::Slice wrap an Option as of glow 0.14. - spin: iris asked for 0.12 while flume (via nokhwa) pins ^0.9.8. Moved to 0.9 to unify; usage is two spin::Mutex imports with an identical API. - block 0.1.6 declares a static of an uninhabited type, a future hard error (rust#74840). Its final release was 2016, so upstream will never fix it -- vendored under third_party/ with Class made opaque-but-inhabited, the same shape its maintained successor block2 uses. Also clears the future-incompatibility report. - eframe/egui 0.35 -> 0.36.1 (no source changes; still resolves winit 0.30.13, so the vendored App Store SkyLight patch and the glow 0.17 dedupe both still hold), rtrb 0.3 -> 0.4, plus cargo update (cpal, pcap, ureq, icu_*, ...). Deliberately held back: glow 0.18 and spin 0.12 would re-split the graph, region 4.0 duplicates against cranelift-jit's ^3, libc 1.0 is a pre-release. iris-gui - Browse opened the OS default folder rather than the disk's own. Two causes: scsi_menu's pick_disk/pick_iso never called set_directory at all, and the Disks tab's "Attach..." seeded a bare relative "scsiN.raw" whose parent is "", so path_row's guard fell through. Both now seed from the current path and fall back to the managed disks dir. - Create-disk used File::create, which truncates, and pre-fills the filename with the disk already attached at that SCSI id -- so a second visit to the dialog silently erased an installed image. It now warns with the existing file's size and gates Create behind an explicit erase checkbox. - Port forwards: added SSH (2222->22) and VNC (5901->5900; host side dodges macOS Screen Sharing, which owns 5900). Telnet 2323->23 already existed. CI - iris-ci chd-sync [ID|all] folds pending CHD diffs back into their bases, refusing to run while the CPU is up -- folding releases the disk backend, which would yank the drive out from under a live guest. - iris-ci quit --sync-chd [ID|all] stops the machine and folds before exit, mirroring the GUI's flatten-on-exit ordering. - sync_chd_disks gained an `only: Option<usize>` selector; None means all. Fold commands use a 3h client read timeout, since recompressing a base routinely outruns the 300s default. Warning-free across 27 iris and 8 iris-gui feature combinations plus the release profile; 360 + 28 tests pass. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adds the volume directory (0x048, 15 x 16 bytes) to the SGI volume header writer so an image can carry named standalone files the PROM boots by name (boot -f dksc(0,<id>,8)<name>), plus a build/dump CLI. - VolumeHeader: parse/mutate a 512-byte header, checksum refreshed after every mutation; voldir + partition-table accessors. - build_image(): raw image from an ImageSpec (voldir files, partition entries, optional raw partition contents); slot 8 sized to cover the files. - mkvh build/dump. Dump validated against media IRIX wrote — an installed 6.5 disk lists ide/sash at the right lbn with a valid checksum; see rules/testing/sgi-volume-directory-layout-verified-on-real-media.md. create_scratch_image() behaviour is unchanged. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Validated against the IRIX 6.5.22 Installation Tools CD, which mkvh dump now reproduces exactly (4 voldir entries, 3 partitions, valid csum): - Partition 8 must span every file the voldir points at — 48736 blocks on that CD, not the 8-block scratch minimum. build_image() sizes it from the placed files, and PartitionSpec::first_block is now Option: None starts a partition where the volume header ends, as the CD does (partition 7 at block 48736). - An EFS filesystem partition is type 5 (PT_SYSV), not type 7 (PT_EFS) — the EFS superblock is genuinely there (fs_magic 0x00072959, fs_size 1280320). mkvh's --part help says so. - dump prints rootpt/swappt. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Load a static ELF32 MSB binary straight into RAM and jump to its entry point, so a bare-metal test binary can be run without building a disk image. - src/elf.rs: static ELF32 MSB ET_EXEC/EM_MIPS reader. Rejects ELF64, LSB, ET_DYN and dynamic binaries by name; sign-extends 32-bit vaddrs so KSEG0 works in both addressing modes. - Monitor `loadelf <file>` / `loadbin <file> <addr>`, and `--load-elf FILE`. - Writes go through the CPU's virtual-address path, then the loaded range is writeback-invalidated out of L1D/L2 and invalidated out of L1I, so a stale decoded instruction can't run. Loading requires a stopped CPU, which is what makes the v1 JIT safe (its CodeCache dies with the CPU thread); jitv2 self-invalidates from the per-page generation counter. Pre-POST RAM: MEMCFG0/1 are 0 at reset, so RAM is unmapped and UnmappedRam swallows writes silently. Two fixes: every load probes the bus (not the cache, which would absorb the probe) at both ends of the range and refuses with an actionable message if nothing is mapped; and --load-elf programs the banks the way POST does first, so a cold start with no PROM works. Verified: a hand-assembled ELF loaded by --load-elf on a cold machine printed over the SCC and spun; reloading a different binary at the same address from the monitor ran the new code (new serial output and marker word). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The PROM has a complete BOOTP + TFTP client and IRIS already answers BOOTP, so `boot -f bootp()<file>` only lacked a TFTP server. Adds a read-only one, default-off, on UDP 69 at the gateway address. - src/tftp.rs: pure RFC 1350 state machine (no sockets), driven by the NAT the way nfsudp.rs is. RRQ only; WRQ answered with ERROR 2; ERROR 1 for a missing file; 512-byte ACK-driven DATA; a short block ends the transfer, including the zero-length one after a file that is an exact multiple of 512; duplicate ACKs never advance; last DATA is retransmitted on timeout, bounded retries then the transfer is dropped. - Octet only, case-insensitive; netascii is refused rather than silently served raw. The embedded PROM image only ever sends "octet". - Paths resolve under the configured root; absolute paths, `..` and symlinks leading out of it are refused. Nothing ever opens for writing. - Enabled by `[network] tftp_dir` or --tftp-dir; unset means no TFTP at all. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A default-off MMIO device (--test-device) so a bare-metal test binary can report to the host without the SCC: SIGNATURE (so the guest can detect it and fall back to SCC-only on real hardware), PUTC (byte to stdout), DUMP (full machine state to JSON, the written value tagging the dump point) and EXIT (terminate with the guest's exit code). Mapped at GIO expansion slot 0 (0x1F400000), which is empty on a stock Indy and otherwise answers with a GIO timeout, so it displaces no real hardware — graphics are at 0x1F000000, slot 1 at 0x1F600000, MC/HPC3/PROM higher still. Enabling it together with the ultra64 dev board, which claims the same slot, is refused. Disabled (the default) the range reads 0xFFFFFFFF and swallows writes exactly as before. The dump carries gpr[32], hi/lo, pc, the CP0 registers by name, fpr[32] plus FCSR/FIR, and identifies R4400 vs R5000 from PRId; values were checked against the monitor's own regs/cop0/cop1. State round-trips through snapshot save/load (unit test plus an end-to-end save/load). Also --cheritest-dump-hook: a guest write to CP0 26 triggers the same dump, for the external cheritest corpus. Strictly opt-in and verified inert by default — CP0 26 is ECC on a real R4400 and the PROM writes it during cache init. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- docs/cpu-test-support.md: how the four features are used together, and which channel carries what back to a CI harness. - rules/testing/loading-code-before-post-ram-is-unmapped.md: MEMCFG0/1 are 0 at reset so nothing is mapped, UnmappedRam swallows the write, and a cached probe can't see it. Plus Indy RAM at 0x88000000+ and the KSEG1 masking trap. - rules/testing/scc-serial-output-from-bare-metal-code.md: IOC serial 1 is SCC channel B (8881), TX needs WR5.TX_ENABLE, and the TCP backend's one-client behaviour silently eats output. - NAT-level TFTP tests: a guest RRQ frame in, DATA frames from the gateway out. - testdev: the PROM's slot-0 probe is at 0x1F46A07C, outside the decoded window. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Dependency hygiene
iris-gui
CI
only: Option<usize>selector; None means all. Fold commands use a 3h client read timeout, since recompressing a base routinely outruns the 300s default.Warning-free across 27 iris and 8 iris-gui feature combinations plus the release profile; 360 + 28 tests pass.