Repository navigation
fuel: add the SGI Fuel (IP34 board, IP35 platform) - #368
Draft
jamesbraid wants to merge 44 commits into
Draft
jamesbraid wants to merge 44 commits into
jamesbraid wants to merge 44 commits into
Conversation
I/O (bedrock_io): Fuel needs Bedrock I/O to route programmed PIO windows to PCI widgets, check inbound DMA permissions and run its two block-transfer engines. Fault reporting and interrupt delivery stay with the block that owns the state, and unsupported accesses are reported. Register map and behaviour are ported from the QEMU model. Node routing (bedrock_ni): Fuel runs as one node with no NUMAlink peer, but the guest still reads and programs these local control words during machine setup. Retain the writes and keep the network fabric out of the model. Crossbar (bedrock_xb): Record the fabric error queues and let software service them, with the outputs available to the Bedrock processor interface. Unsupported queue reads return zero and writes are logged and ignored. Local bus (bedrock_lb): Add the node and region registers, atomic scratch aliases, error and vector status, and the MicroLAN master that board identity parts sit on. The tests drive it together with the I/O, node-interface and crossbar blocks it reports through, which land in this same commit.
The Fuel CPU receives interrupts and timing events through Bedrock PI. Model the fitted processor slot and its node callbacks while keeping unconnected graphics control explicit.
Fuel reaches its AMD flash through executable PROM aliases and programming windows. Share the array bytes and persistent store while preserving the command and erase state of each flash part. The configuration block's CPU type word is 1, the R14000, as the IP35 PROM's own configuration editor lists it (0 for the R10000 and R12000, 2 for the R16000); a test pins it.
Fuel routes PCI configuration, DMA and interrupt packets through two XBridge heads. Each head owns a PCI bus, as the Octane's Bridge does: the bus holds the head's functions, decodes their BARs and combines their interrupt pins, and the head supplies only what is its own. That is how a processor access becomes configuration cycles and byte order (from a device window's register, or from Control for an alias), the translation table and DMA, and where an interrupt pin goes. Whole-page BAR runs of the device and alias windows are served from the head's own table, so the bridge shares the machine memory map without allocating more Physical tables. A board attached to one of the crossbar's external ports raises its interrupts as crosstalk packets, the same way the PCI heads do. Route them through the same sender, so the Fuel's graphics board reaches the Bedrock's processor interface with no path of its own, and say whether the destination took the packet. The crossbar answers with the Crossbow's widget 0 register map, so it takes its offsets from the Octane's Crossbow model instead of restating them. What stays separate is behavior that differs between the two: the XBridge crossbar's status register carries the requesting port, wide and malformed accesses set the access-error status and answer zero, its interrupts go out as crosstalk packets to any destination, and it resets the heads and ports its fences select.
The Fuel console first passes through the L1 system controller. Reuse the shared 16550 core and keep controller framing, power commands and identity records in its protocol model.
Fuel enumerates a Lucent OHCI controller on PCI. Provide its registers and descriptor scheduling through the USB function interface while leaving devices unattached in the machine configuration. The frame counter follows the machine clock the board hands the controller, and every register read and write first delivers the frame boundaries that clock has passed. Advancing it only from the board's poll, which runs between CPU batches, left HcFmNumber at zero after the guest's own 1 ms wait had expired, and the Fuel PROM reported that SOF did not start within 2 ms. The sync holds one lock from reading the clock to applying the frames, so a timer thread cannot leave a concurrent reader behind it. Entering UsbOperational from Reset or Suspend re-anchors the frame: it loads HcFmRemaining from HcFmInterval, toggle included, and increments HcFmNumber, with the first SOF one frame later (OpenHCI 1.0a 6.2.1, 7.3.2, 7.3.3). The tests cover that entry with frame numbers at and around the overflow flag. Add two low-speed USB functions for the OHCI root ports: a HID boot keyboard and a HID boot mouse, each with one configuration, one boot interface and one interrupt-IN endpoint. They answer the standard requests (descriptors, SET_ADDRESS taking effect after its status stage, SET_CONFIGURATION, status and interface queries) and the HID class requests (GET/SET_REPORT, GET/SET_IDLE, GET/SET_PROTOCOL), and report host keys and pointer moves as boot reports. Reports queue one per change so a key tapped between two polls still shows both edges. Written from the USB 1.1 and HID 1.11 specifications (boot descriptors from appendix B) and the HID Usage Tables, with no code from another emulator. The wheel, remote wakeup and the host layout translation that the PS/2 path has are left out. Ohci::attach loses its test-only gate so a machine can plug the devices in.
The JIT reads code pages, and asks for their generation counters, at plain physical addresses, through the executor's sysad. Everywhere else sysad is also what the cache fills from, so a plain address there is memory. The Fuel's sysad is the uncached connection: it takes bits 58:57 of the address as the uncached attribute and decodes a plain one as Hub-special space, which holds RAM only in its first 256 MiB. Its compile pool was started on the cache's own view of memory instead, so the pool and the CPU's inline compile and page lookup read code through two different objects, and a flush restarted the pool on the CPU's. The executor now keeps one bus for cacheable memory, defaulting to sysad, and the page lookup, the inline compile, a flush's restart and `j2 inline off` all use it. A board whose uncached connection decodes differently gives it the cache's view with set_cached_bus and starts the pool on the same object. No other machine changes: the two are the same object there.
Build the Fuel IP34 board around its R14000, Bedrock, XBridge, IOC3 and dual-channel ISP12160. Use one Physical memory table with sparse processor and peripheral views. Uncached byte and halfword stores reach a device through BusDevice::write_narrow_from, which each window forwards at the device-local address; only the memory controller's ECC view reads more than the low bits of the register. With the jitv2 feature, start the compile pool after the memory windows are published, as the Octane and O2 do. Each worker copies the cache geometry once as it starts, and without the windows that geometry has no inline load or store path. Workers read code through the CPU's cached bus, the view the cache fills from, which serves plain physical addresses; the uncached views would decode them as node registers. The machine describes where its memory can answer to the CPU: the four 1 GiB slots Bedrock's controller places its two 256 MiB banks in, and the reset PROM. Its disks on both ISP12160 channels are flushed at power-off, quit and exit like the other machines', so a copy-on-write overlay keeps its record of held sectors after a guest `halt -p`. The processor is the R14000 at revision 2.3 (PRId 0x0f23), the revision a public software inventory of a Fuel prints, where the Octane's part reports 2.4. The raw CP0 word, the FIR and the 128-byte lines are taken from the Octane part, not read from a Fuel. Like the Octane's R14000 it reports "R12000" as its name. The machine loads its PROM through prom_image. Feed the IOC3 PS/2 controller from the window, VNC and CI input, and let a USB keyboard on root port 0 and a USB mouse on port 1 share it. The Fuel's manual shows PS/2 as the standard keyboard and mouse, so ps2_input under [fuel] defaults on and usb_input defaults off; setting usb_input fits the USB pair, and ps2_input = false leaves the PS/2 pair out. The monitor's ps2 command reaches the keyboard and mouse too. PROM loader (prom_image): Add a device-independent loader for PROM images. It accepts a raw payload or a version-six stored or gzip container, decodes the recognized containers explicitly and reports malformed inputs with their path before any bytes reach guest memory. Config profile (config): The Fuel is a new machine profile with two memory banks, wide SCSI buses, no Ethernet adapter choice beyond its built-in one, and no graphics board by default. The [fuel] section selects the serial console (the L1 controller or either IOC3 port), the L1 TCP port and log, and the persistent boot flash store. l1_revision and brick_serial replace the L1's reported firmware revision (default 1.48.1) and brick serial (default EMUN00). ps2_input defaults on and usb_input off, as the Fuel's manual shows PS/2 as the standard keyboard and mouse; setting usb_input fits a USB keyboard and mouse, and ps2_input = false leaves the PS/2 pair out. The key names the part: machine.cpu = "r14000" selects the Fuel's r14000_500, and a Fuel config cannot claim another processor. The Octane's R14000 is revision 2.4; the Fuel's is 2.3.
The test slept 150 ms and required the pushing thread to still be unfinished. The board thread's hold was a fixed 4 s sleep, which a loaded host could outlast before the test looked, so the refused store could complete and the assertion fail. The hold now lasts until the test releases it, and the test waits for the push to be refused before it asserts.
The board assumed the Octane: its interrupt packets went only to HEART at widget 8, and it took the processor's addresses in the IP30 widget windows. A Fuel's processor reaches widget 13 through Bedrock, which hands the board widget offsets, and the board's packets cross the XBridge's crossbar to Bedrock like any widget's. Add a constructor for such a machine. It takes a packet sender for the interrupts and decodes every address as an aperture offset. The two choices were hard-wired into the board; they are now one packet sender (the Octane's checks for HEART's widget and register and drives its line, and a packet to anywhere else is refused as before) and an explicit aperture mode chosen at construction. The Octane's constructor and behaviour are unchanged, and nothing on its store path is touched. The debug register dump no longer lists the heart widget, which is the Octane sender's business now. A test routes a packet to a widget other than HEART and requires the sender to get it, not HEART's line.
Every Fuel has a VPro graphics slot: a Fuel IRIX inventory lists its board under xtalk/13 and OpenBSD finds Odyssey at crossbar widget 13. Build the board there when the machine is given a V12 or a V10, through the widget-offset constructor, and keep none, the serial machine, as the default. The XBridge now reports link 13 alive, the board's DMA enters Bedrock's inbound path as widget 13, and a link reset of port 13 resets it. Its interrupt packets cross the crossbar to Bedrock like the PCI heads'. The status bar's activity (SCSI, IOC3 and Ethernet) and the CPU's Compare ticks reach its LEDs as on the Octane. IRIX's VPro driver writes each processor interface's graphics flow-control registers at attach and tears the board down when the credit counter reads zero, so each interface keeps those registers as plain storage. Nothing counts stores or returns credits. With PROM 6.210 the board passes the graphics diagnostic, and IRIX 6.5.30 with the VPro driver lists Graphics board: V12 and draws the X login screen on it. Input comes from the PS/2 pair the Fuel already has. Configuration accepts the board on the Fuel too, see the config note below. Tests build a Fuel board with each board and check that the processor reaches the board at widget 13 and finds its link alive, that its interrupt packets set and clear a processor interface's pending bit, that a link reset of its port resets it, that a headless Fuel has nothing there, and that the processor interfaces keep their graphics registers. Config (config): A Fuel is reported with both the V12 and the V10, so take either with [graphics] board; the other boards stay refused, with a message that names the Fuel's choices, and none, the serial machine, stays the default. The doc comments for the two boards now say they fit the Fuel as well as the Octane. The Fuel's validation case now accepts both boards and refuses the V6.
Document the supported serial configuration, image inputs, the host input options and the explicit limits for graphics, USB devices and snapshots, in the feature list, hacking notes, debug notes, the sample config and a Fuel page. The page also says how the PROM's stack in primary data-cache lines is served: by the CPU's staged-line support, with nothing special in the memory controller.
…sses The R10000 drives a two-bit uncached attribute on the system bus. For an unmapped xkphys access it is address bits 58:57; for a mapped reference it comes from the TLB's uncached-attribute field, which EntryLo0/1 bits 63:62 load (R10000 User's Manual 007-2490-001). EntryLo already keeps those bits on the family, and a TLB entry holds them, but the entry's physical base dropped them, so a mapped uncached page always reached attribute zero. Carry them to physical bits 58:57 only for pages the model's C table decodes as uncached, so cached mappings are unchanged. The TLB already holds that table for its shadow entries; reading it there, and recomputing each entry's base when a table is installed, avoids a second decode of C. An entry with no attribute bits set, the usual case, skips the C table. The attribute reaches the bus only on a board that decodes physical bits 58:57. The Octane, Indigo2 and O2 mask the physical address to 40, 32 and 32 bits before the bus, which folds it away, and a test shows that at the executor. The R4400 and R5000 never store the bits. Tests cover the attribute and the board masks, and the C table (a value the model decodes as cached carries nothing; a table installed after the entry was written decides). The uncached-attribute comments cite NEC U10278EJ4V0UM, the fourth edition of the VR10000/VR12000 user's manual, section 11.3, by document number; the manual itself is not added to the repository.
Bedrock memory configuration changes the RAM decode. Keep ordinary CPU and DMA memory on Physical directly, divert diagnostic pages through MD, and update their generation state when memory configuration or ECC changes. The ECC view overrides write_narrow_from to take an uncached SH's check word from the whole source register, at the position Fuel PROM 6.210's memory test uses. Every other view stores the architectural low bits.
jamesbraid
marked this pull request as draft
October 31, 2026 05:28
Collaborator
Author
|
wip, doing some rework and cleanup |
jamesbraid
force-pushed
the
fuel-ip35
branch
14 times, most recently
from
November 2, 2026 03:10
24e0013 to
e49c3b0
Compare
Each widget's first 2 GB of XIO space also appears at physical 0x8_0000_0000 + w * 2 GB. For the Bridge that window holds the 16 MB small window and, from offset 0x4000_0000, the 32-bit alias of PCI memory space from PCI address 0 (Bridge ASIC specification, p. 52), with the bytes placed by Control's memory swap bit rather than a Device(x) register (p. 55). iris mapped neither, so any PIO there was an unmapped physical access. IRIX 6.5.30 reaches a BAR this way. After a warm reboot it numbered a PCI-to-PCI bridge in slot 5 again, this time with a memory window of 0x80_0000 to 0xff_ffff, and read the NVMe controller behind it at 0xF_C080_0008 (PCI memory 0x80_0008). The read bus-errored and the kernel panicked. The Bridge now publishes the alias as a ninth CPU window, so a BAR it decodes whole becomes a run the processor reaches directly, as the device windows' runs are. Ip30Bus maps the 2 GB window to the Bridge and puts alias runs there instead of in the small window; a widget with no 2 GB window maps no such run. The specification calls 16 MB to 1 GB reserved without saying what an access does, and iris answers it with a bus error. An alias cycle nothing claims is a master time-out whose capture names device 0; the specification does not say which device it names. The address map's section on XIO addressing put widget 15's window at 0xF_0000_0000, against its own physical map and the address IRIX uses; it now says 0xF_8000_0000. The 64-bit alias at 0x8000_0000 and PCI I/O at 4 GB, which only the 64 GB window reaches, are still not modelled.
The PCI layer now has an Octane windows section in docs/pci.md (the Bridge's 2 GB window, what its reserved range answers, and what is not modelled), and the open-items note records what is deferred and what is approximated: restore not being a reset, the AIC-7880 chip reset, the missing external ATE RAM and the per-device reset pins. clanker/plans/pci.md lists what follows this change: the XBridge and PIC moving onto the shared layer with their machines, the XIO PCI carrier, card cage and NVMe in real slots, and the reset work that waits for the machine rework.
jamesbraid
force-pushed
the
fuel-ip35
branch
5 times, most recently
from
November 8, 2026 00:28
5467215 to
7571c3a
Compare
Collaborator
Author
|
good to go |
jamesbraid
marked this pull request as ready for review
November 8, 2026 00:55
jamesbraid
marked this pull request as draft
November 8, 2026 02:13
A CPU's cache, its decode cache and its compiled code reach RAM through ppmem's window, and every CPU and Physical's direct paths share that one window. The R10000-family PROMs use the caches as working memory before memory is set up: lines made valid with Index Store Tag and Index Store Data hold a stack or code while uncached accesses, which bypass the caches (NEC VR10000 user's manual p. 75), see memory. The Tezro's processors hold lines for the same addresses with different contents at once. One shared window has no room for any of that. PpMemSpace::add_cached_view gives a CPU a window of its own. Every mapping laid in the shared window is laid in each view as well, and a view publishes its bitmap to that CPU's inline fields, so the CPU reads its view through the same base pointer and bitmap test it used before. hold_line_page turns a page of a view into private memory, starting as a copy of memory, and release_line_page lays memory back when the last line goes, dropping what the page held. A remap saves and restores the held pages around it. A page with no memory behind it is refused. One in a region the window maps only in part takes the whole region in that view, reading zeros where nothing is mapped, because the region bitmap is all a CPU tests: the O2's POST holds lines for page 0 before CRIME maps the rest of its region. Nothing holds a page yet. The views are not coherent with each other or with DMA. The generic machine, the Octane, the O2 and the IP27 machine give each CPU a view now. Physical and the devices that read the window directly keep the shared one. Nothing on a load, store or fetch changes. The CPU no longer takes over the shared window's bitmap, so set_bitmap_sink and add_bitmap_sink lose their last callers and go.
The Fuel's and the Tezro's PROMs run code from primary instruction lines they make valid with Index Store Tag and Index Store Data, and on iris those words differ from memory once memory is set up there (measured on the model, not on hardware). Compiles read memory and compiled code is shared by every CPU, so code compiled from memory would run in place of the lines. Upstream iris has no machine that runs code from a held page yet: the O2 keeps only a stack in lines and runs POST uncached, and the Octane's lines name no memory. This is for the Fuel and the Tezro. The first CPU to hold a page now puts GEN_HELD on the page's generation counter, which retires what was compiled there, and the last release takes it off with an ordinary bump. A compile that finds the mark publishes no code for that generation and denies every offset, so arrivals interpret the page from the CPU's own view without asking again. The first compile after the release allows every offset once more. The release lowers the counter, so publish treats any change of generation as new bytes, not only a rise. ppmem owns the mark, so it is one mark however many CPUs hold the page, and a remap moves it to the counter that backs the page afterwards. All of it is at compile time. Dispatch and compiled code are unchanged, and every other page stays compiled. Without the denial, four Tezro processors asking for the same held PROM page took 65-77 s to the BASEIO monitor against 38-42 s with it (an earlier version of this change, jitv2 loop-profile builds).
…view The R10000-family PROMs keep stacks and data in cache lines they make valid with Index Store Tag and Index Store Data. The O2's POST tests page 0 uncached while its stack lives in secondary and primary data lines for the same page, the Fuel's and Tezro's stacks sit in primary data lines for 0x100000-0x107fff, and on the Tezro every processor holds those lines at once with its own contents. The shadow cache kept the tags and data arrays for diagnostics only, so a cached access read memory. A tag change that makes a primary data or secondary line valid now holds its page in the CPU's cached view and writes the line's data array into it, since Index Store Tag writes the tag array alone (NEC VR5000/VR10000 instruction manual pp. 24-25). Loads, stores, fetches, the decode cache and compiled code read the view as before and change not at all. Uncached accesses bypass the caches (NEC VR10000 user's manual p. 75) and keep seeing memory, as do other masters, since the views are not coherent. A tag that names another line, or none, ends the line, and the page goes with its last line. Index Store Data into a held line writes through. The tags stay the only line state, plus a held bit. The O2's R5000 POST keeps its stack the same way, in primary data lines for page 0 made valid by Index Store Tag (D) with TagLo 0xc0, and tests page 0 uncached meanwhile. An R5000 primary data tag has the R10000's PTag and PState fields (NEC VR5000 user's manual U11761EJ6V0UM p. 133), and a store hit on a write-back line makes no bus request (p. 243), so a valid one holds its page too. The R5000 has no Index Store Data, so the page starts as memory. Its instruction lines hold nothing: with no Index Store Data to fill one, it could hold only what memory holds. Every line the shipped PROMs stage ends by Index Store Tag, none is written back, and none is read back with Index Load Data while it holds a page, so the writeback and invalidate operations stay as they were. The R12000 zeroing a primary data tag at Index Writeback Invalidate ends a line like any other tag change. A secondary doubleword puts TagLo at the lower address. The manuals fix only that TagHi is the doubleword's high word and TagLo its low word (MIPS R10000 user's manual p. 201, NEC VR10000 user's manual p. 289); which address each pairs with is inferred, not established, from shipped PROMs. PROM 6.210 on the Fuel and the Tezro stages code with the word at A in TagLo and the word at A + 4 in TagHi, 990 pairs in a Tezro boot, and its staged code equals its image only this way. The IP35 boot-flash PROM's staging pairs them the same way: simulated with the other order, 378 of its 562 staged fetches break, every trampoline fetch among them. With the other order the Tezro's PROM falls back to running its cache test uncached, which took twice as long to reach the BASEIO monitor. Limits: a page, not a line, is private, so the rest of a held page shows memory as it was when the page was taken, and nothing is coherent with other CPUs or DMA. A snapshot taken while lines hold pages is refused at restore. Lines that name no memory, like the Octane's tag test patterns, hold nothing. `l2 probe 0` lists the pages held.
Upstream iris has no machine that needs this yet. The Fuel's and the Tezro's PROM 6.210 copies itself to memory from code it stages in primary instruction lines with Index Store Tag and Index Store Data (I) and runs through cached xkphys, and once memory is configured, memory at those addresses holds something else. Without the lines the PROM hangs on iris at "Copying PROM code to memory ..." (measured on the model). A valid primary instruction line now holds its page in the CPU's view like a data line, with each word written there as the instruction it predecodes. A primary instruction word is 36 bits of predecoded instruction (NEC VR10000 user's manual p. 288, established). Neither manual gives the layout, so it is inferred from the words PROM 6.210 stores, and only its eleven sampled classes decode. A word of any other class leaves memory's word in the page, where hardware would run it. Index Store Data (I) into a held line writes through. The PROM gets the predecoded form of other code from the hardware: it runs a secondary line it staged, which refills a primary line, and reads the words back with Index Load Data (I) to stage them itself (measured on the model). The model does not refill on a fetch, so Index Load Data (I) in a set a held secondary line maps to now answers with that line's words predecoded, as if it had been refilled, until Index Store Data (I) writes the set. A guest's own pattern in the set reads back as written (MIPS R10000 user's manual pp. 201-202). An instruction outside the eleven classes comes back in a form only this model reads, bits 35:32 set over the instruction, which takes predecode classes 0x78-0x7f. Nothing on a fetch, load or store, and nothing in the decode cache, changes. A page held only for code also answers cached loads with the code's bytes, where hardware would read memory.
The O2 kept POST's stack in bank 0 and, while a primary data tag for page 0 stood, pointed the decode table at a page of its own for the uncached path, switched by a hook on every Index Store Tag (D). The CPU's cached view holds those lines now, with the bank, the decode table and the rendering engine on memory meanwhile, so the side page, its hook in the shadow cache, the slot-1 mapping it needed at reset and MipsCache::set_pd_tag_store_hook go. A snapshot taken during POST by an older iris carries the side page but no cache lines to rebuild the stack from, and is refused.
Fuel uses two independent SCSI buses behind one ISP12160 function. Reuse the ISP1040 command engine and let the part trait own the firmware, register and channel differences. A bus reset reaches every attached target as unit attention rather than a media change. Keep the reset attention on the shared target interface so a controller can notify each device through the same bus. The ISP12160 is its only caller: the WD33C93A, AIC-7880 and ISP1040 models do not call it, so their targets behave as before. A bus reset restores each disk's write cache bit per channel: a reset of one channel leaves the other's disks alone, and a chip or soft reset restores both. The engine changes reach the Octane's ISP1040: mailbox commands now run with dispatch held, and the target interface gains the bus reset. The Octane's IRIX 6.5.30 SCSI disk (Octane2, R10000, 256 MiB, V12, jitv2, release build, headless, NAT) boots to the login prompt and runs commands on this branch's tip and on main c6dea8c: login after 126 s on the branch and 109 s on main in one run each (host load makes the times indicative only), the same `hinv` listing of both integral controllers and the disk, and the same command output.
The Fuel's and Tezro's PROMs keep their stack in primary data lines for 0x100000-0x107fff and run code from primary instruction lines at the PROM's own addresses before they have configured memory. The cached view refuses a page with no memory behind it, so those lines would hold nothing and the PROM would read the bus. allow_unbacked_lines names ranges where a page may be held with nothing mapped behind it. Such a page starts as what the cache's bus shows there, and its region is the view's while it stands, as for any held page. A remap keeps the page, so memory arriving mid-phase does not lose the stack. jitv2 stays off a held page by the mark ppmem puts on the page's generation counter, but only on ppmem's own counters. The IP35 boards' compiles check other ones: Bedrock's for RAM, and for the reset PROM that the bus maps over memory at 0x1fc00000 the flash's, which is neither ppmem's nor Bedrock's. A page held there carried no mark, so jitv2 could compile the image's bytes for a page whose lines hold other words, as a PROM that stages code in instruction lines at its own address makes it. The cache now puts the same mark on whatever counter its bus gives the page when that is not ppmem's, and takes it off with the page's last line. That runs at CACHE instructions only; loads, stores and fetches are unchanged. Test branch only.
The Fuel's PROM keeps its stack in primary data cache lines for 0x100000-0x107fff before it has configured any memory, so those lines have nothing behind them when they are made valid. The cached view that the CPU reads memory through can hold such lines only in places declared for it. Declare all four bank slots as places lines may be held before memory is mapped. Without the declaration the PROM's first stack access takes a data bus error.
jamesbraid
force-pushed
the
fuel-ip35
branch
5 times, most recently
from
November 9, 2026 13:48
4a67fd2 to
1c16d9c
Compare
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.
This adds the SGI Fuel: a 500 MHz R14000 on a Bedrock node with 512 MiB, the dual-head XBridge, the IOC3 (Ethernet, serial, parallel, PS/2), the two-channel ISP12160, the L1 system controller, AMD boot flash and OHCI USB. PROM 6.210 passes its diagnostics and boots IRIX 6.5.30 to the 4Dwm desktop, and with a V12 board SGI Quake, SGI Doom and Performer draw. Most devices are ported from my sgi-origami QEMU branch.
This is based on #422 (the shared PCI layer) and carries #448's five commits (each CPU's cached view of memory) until it lands; both drop out on rebase. The XBridge uses the shared PCI layer as the Octane's Bridge does: each of its two heads owns a
PciBus, implementsPciHost, publishes its device and alias windows as CPU windows with the byte order chosen when they are published, and takes its interrupts through the shared combiner (IntxRouting, with the IOC3's SuperIO interrupt as aBoardIrq), so it has no slot table, BAR-mapping code or interrupt routing of its own.Processor
r14000_500: R14000 rev 2.3 at 500 MHz with a 2 MB secondary cache, as the IP35hinvdumps show. It is the only entry in the Fuel'sCPUS.cpu = "r14000"now meansr14000_500, andcpu = "r10000"is refused. Leavingcpuout takes the default.fuel.toml.exampleis updated.Fuel-only CPU behaviour
cached_bus, which the JIT's page lookup, its inline compile, a flush's restart and the compile pool all use. It issysadon every other machine. The Fuel'ssysadis the uncached connection, which decodes a plain address as Hub-special space, so the Fuel gives the executor the view its cache fills from and starts the pool on that same object. This replaces the earlier restart fix.PS/2 through the IOC3 is the default keyboard and mouse;
[fuel] usb_inputadds USB HID. There is no audio: the Fuel had none built in.Testing
cargo test --workspace --no-run --features jitv2builds at every commit;cargo test --features jitv2 --libpasses at the tip (3620 tests) apart fromno_process_exit_bypasses_the_flush, which fails on main itself.jitv2) boots to login in 106 s with ALL DIAGS PASSED, network, DNS and rsh, and no lines held at login. On the same build an O2 with its default R5000 (77 s), an Octane (84 s) and an Origin 200 (84 s) boot to login and halt. At the previous head it booted in 122 s, and in 180 s with all compiled code thrown away every 25 s (fivestop; j2 flush; startcycles from the monitor), which checks that the JIT's page tracking and compile pool rebuild correctly mid-boot on the Fuel's split cached and uncached buses. Both runs print ALL DIAGS PASSED.hinvshows the R14000 rev 2.3 at 500 MHz, 2 MB secondary, 512 MB, both QL12160s, the V12, ef0 and the OHCI controller. The network answers ping, DNS and rsh,halt -pexits 0, and the cached view holds no lines at login (l2 probe 0: 0 valid lines).Performance
No cost to other machines:
iris-bench ab(frombench-ab-pr) against #448 (r10k-cache-line-staging), release featureslightning,jitv2,gpujit,idle-pause,hostgl, concurrent pairs on a busy host, 20 rounds, Indy R4400. The suite is -1.2% [-2.7%, +0.7%] (99.9% interval, B over A, negative is faster), and no kernel is flagged. Host cycles per guest instruction are -3.9%. 25 noisy kernels are inconclusive, so the claim is no slowdown beyond +0.7% on the suite, not zero.