Skip to content

octane: cleanups, memory-map tests, lightbar and activity lights - #351

Merged
techomancer merged 15 commits into
techomancer:mainfrom
jamesbraid:octane-cleanup
Oct 29, 2026
Merged

techomancer merged 15 commits into
techomancer:mainfrom
jamesbraid:octane-cleanup

Conversation

@jamesbraid

Copy link
Copy Markdown
Contributor

Follow-up to #342 on top of the Octane's move onto Physical. The commit messages have the details.

  • Ported-device tidy-ups and leftovers removed (114-byte NVRAM format, board records into w1::sgi, synthetic fixtures).
  • Tests that pin the Octane's memory map.
  • Front lightbar and SCSI/network lights in the status bar.

golden.rs pinned the bus's reply streams to FNV digests and head bytes
generated once from per-master code that no longer exists. A digest says
a stream changed but not what it should be, and nothing in this repo can
regenerate the fixtures. The multi-part cases it covered (Search ROM,
Read ROM, Skip ROM with Read Memory, a bad Match ROM over a DS2502,
DS2501 and DS2505 on one wire) now sit in tests.rs and assert the
wired-AND the protocol defines, computed from the parts' own ROMs and
streams. The w1 tests' MAC constant is now a made-up address.

sgi_nic's mac_nic and board_nic only boxed the result of
ethernet_address_part and board_record_part so it could be added to a
w1::Bus. HEART, the Bridge and the IOC3 box the part themselves, and the
wrappers, which left two names for each constructor, are gone.

Name the qemu-sgi-origami source each of heart.rs, heart_mem.rs,
sgi_nic.rs and the w1 modules was ported from, as ioc3.rs, ioc3_eth.rs,
isp1040.rs and rad1.rs already do, so the provenance is uniform.
Ioc3::set_parallel_backend, Bridge::set_dma_64bit and w1's slot_wired
exist so tests can exercise paths no machine uses yet. In a normal build
they are dead code. Compile them only for tests and say why in each doc
comment.
A message a guest driver can provoke on every access goes to dlog!, not
stderr: an unsupported register width, a ring that is not programmed, a
DMA that misses memory, a target error. A guest that repeats one would
flood the host console, and nothing could silence it. dlog! output is
per module and can be turned off.

The ISP1040 messages use the existing scsi module, and the target error
is also recorded in the device's note log like its siblings. RAD1 had no
module, so it gets rad1.

A host failure is not guest-triggered and stays on stderr. The IOC3's
NVRAM save fails when the disk is full and is retried on every scheduled
save, so it printed on each one. It now prints once until a save
succeeds again.

HEART and the Crossbow already record their refusals in bounded lists
the monitor reads, and the Bridge reports its own at log debug level,
so they need no change.
The Octane Compare-across-the-wrap test armed a real hptimer one-shot
and polled for IP7 for up to two seconds, so it depended on host
timing and was compiled out under ci_clock.

Move the delay arithmetic into compare_delay_ns and assert its result
directly: a target just past the wrap waits the short distance, a
target equal to Count waits a full wrap, and one behind Count waits
out the wrap. The test no longer sleeps, so it runs under ci_clock too.
Add bus-level tests for parts of the map the other tests leave open: a
valid descriptor over an empty bank, the PROM's bank-size probe answers,
a bank above 4 GiB, a bus master reaching the guarded 16 KiB, and the
alias sharing page generations with SDRAM under jitv2.

One test shows that the window path (mem_ptr) reaches the bytes at
0x2000_3000, because the ppmem window maps the whole 32 MiB unit, while
an uncached read faults. Real HEART faults cached accesses there too. It is named as
a limitation and listed in docs/octane-ip30.md, so a change to it is
deliberate.
A descriptor write rebuilt the bus entries and cleared and remapped the
ppmem window every time, including when the PROM rewrites the same
words. That empties the window under a running CPU for no change and
sends its cached accesses through the bus meanwhile. Compare the bits
the decode reads and return early when they match; the monitor still
sees the words written. A real change already bumps every page
generation in the rebuild, and a test now says so.
The bus's miss list and the HEART and Crossbow unsupported-access lists
keep their first 64 distinct entries. Once full they still took the lock
and scanned the list on every access, which a guest polling an absent
register does continuously. Set a flag when the list fills and return on
one relaxed load, as the O2's miss list does.
A swapped DMA transfer, which is every one on a slot with the swap bit
clear, built a spanning vector and moved each byte through an index
calculation, for reads and writes alike. Disk payloads are page aligned
and a whole number of units, so the common case needs none of that.

When the start and length are whole 4 or 8 byte units, read straight
into the caller's buffer and reverse each unit where it lies. A write
reverses a copy on the stack, or on the heap past 4 KiB, and stores it
in one go. Other transfers keep the byte-exact path. The test places
aligned and unaligned transfers around the 4 KB split and the stack
copy's size under each swap rule and checks every byte. Not measured on
this base.
The 114-byte register dump came from an earlier port of the chip and
nothing writes it any more. Keeping a second reader meant a second
layout to describe and test. The 512-byte image is the only format
now. Any other size is ignored with the existing warning.
The board-record format and the parts built from it only make sense on
a 1-wire bus, and the module that owns the bus already holds the other
Dallas parts. Move dev/sgi_nic.rs to dev/w1/sgi.rs and point the IOC3,
the HQ4, the Octane machine and the w1 tests at the new path.

The moved file's tests also carried barcodes, a part revision and an
Ethernet address read off real boards. Use the synthetic barcodes and
part numbers the machine's own records carry, and a made-up station
address, so nothing in the tree is a real unit's identity.
A pass over the Octane's files for code nothing uses. None of it
changes behaviour.

- Ioc3Config::ethernet_part_serial was always the one shared constant,
  so the field only held a second copy. The wire takes the constant.
- Ioc3::service and its helper are called by tests alone. Compile them
  for tests only and say so, instead of leaving a public method that
  reads as part of the periodic machinery.
- WIDGET_GFX_FIRST had no user.
- The ip30 test rig kept an Ioc3 handle behind allow(dead_code). The
  bridge already holds the chip.
- The w1 tests spelled the Ethernet part's serial out three times.
- A format! with no arguments in the HEART bank check, and an IOC3
  comment that named a service thread the chip no longer has.
The Octane's bus is the shared Physical, but several notes still
described the old arrangement or the Octane as unfinished.

The bring-up note was a log of an early bring-up: "where it stands", a
not-done list that the working machine has since finished, and a second
half for the full machine. It described the one-wire parts through a
type the tree no longer has and said the processor module's part sits on
the Bridge's wire, which is wrong now that HEART has its own MicroLAN.
Reduce it to what the PROM insists on and what booting through to IRIX
added, with the memory-sizing entry corrected to the probe the code
models. INDEX.md now lists it as a rule rather than an open item.

The Octane guide, the device-timing note and the changelog said nothing
polls. The IOC3's receive thread looks for host input every 2 ms, one
per fitted serial port; everything else is paced by hptimer one-shots.
State both. The guide's limitation entry now says why a cached access to
the guarded 16 KiB reaches the bytes while an uncached one faults, and
its provenance sentence no longer claims the same behaviour and
approximations as the models it was ported from. debug.md says a
device's own refusal is not in `ip30 unmapped`. The changelog gets an
entry for the memory and bus changes in this series. Stale names of the
bus type in two comments and the test header are corrected.

HACKING.md still opened with three workstations and described each
machine as having an embedded PROM fallback. The O2 and the Octane are
their own machines (CRIME, MACE and GBE; HEART, the Crossbow and the
Bridge) and have no embedded PROM, so add them and say so. FEATURES.md
and the VALID_BANK_SIZES comment said only IP28 accepts 256 and 512 MB
banks. The Octane's banks are matched DIMM pairs of 64 to 512 MB, so the
Indy and Indigo2 limit is now stated as theirs.
The Octane created the shared activity word but handed it only to the
graphics board, so the SCSI and Ethernet lights never came on. Give it
to both ISP1040 controllers and the IOC3 Ethernet, as the Indy does for
its SCSI and Ethernet parts.

The controllers set the light for the target a command runs against,
for ids 0 to 5, whichever bus it is on. The Ethernet sets transmit when
frames go out and receive when one is delivered to the guest.
The system-board IOC3 drives the lightbar from its first two
general-purpose pins: pin 0 the white power LED, pin 1 the red fault
LED, 1 lit (Linux leds-ip30.c). Mirror them into the status bar's
persistent front LED, white as the green LED and red as red.

The update runs after every register access, so a write to a pin
register, a write to the pin-data register and a reset all reach it. It
only applies to the system-board IOC3. The polarity is one constant.
The model read input 2 as an Octane/Octane2 product pin, high on an
Octane and low on an Octane2. An Octane2's PROM Command Monitor reads pin
data 0x12d: inputs 2 and 3 both high, and nothing public shows a pin that
tells the two machines apart. Drive both high on every Octane board; an
Octane's inputs are unmeasured and assumed the same.
@techomancer
techomancer merged commit 0960ea1 into techomancer:main Oct 29, 2026
14 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.

2 participants