Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ hashes are given where a change is easiest to understand by reading the commit.

## November 2026

### R10000 family fixes, R12000 and R14000

- The R10000 family has 44-bit virtual and 40-bit physical addresses, FrameMask and a 28-bit EntryLo PFN, picks the TLB refill vector by address space, invalidates overlapped TLB writes (Status.TS), and completes uncached stores nothing answers. Partial LWR keeps the upper word, and the cache diagnostics (Index Store Data, secondary tag mask, Config size) work.
- `cpu` takes the parts each machine shipped with, such as `r12000_360` on the Octane, or a family name for the machine's own. The Indy and Indigo2 R4400 is now rev 5.0 at 150 MHz, the O2 R10000 rev 3.4 at 250 MHz, and an Indy no longer takes an R10000 (the R10000 Indigo2 is the IP28). The R12000 and R14000 are new.

### Boot test before publishing

- `build.yml` can boot IRIX 5.3 to a login prompt on Linux, macOS and Windows
Expand Down
6 changes: 3 additions & 3 deletions FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ the first `[section]`, because TOML tables continue until the next header.
| Key | Default | Values and behavior |
|---|---|---|
| `machine.profile` | `indy_ip24` | indy_ip24, indigo2_ip22, indigo2_ip28, o2_ip32 (configured by `[o2]`, see [the O2 guide](docs/o2-ip32.md)), octane_ip30 (configured by `[octane]`, see [the Octane guide](docs/octane-ip30.md)). |
| `machine.cpu` | `r4400` | r4400, r5000, r10000; CPU/ISA choice is independent of build features. An O2 takes r5000 or r10000 (an r4400 is refused when the machine is built); the Octane is r10000 only. |
| `machine.cpu` | the machine's first | A family (`r4400`, `r5000`, `r10000`, `r12000`, `r14000`) or a part (`r14000_600`); independent of build features. Indy and `indigo2_ip22`: r4400, r5000; `indigo2_ip28`: r10000; O2: r5000, r10000, r12000; Octane: r10000, r12000, r14000. The first listed is the default. |
| `machine.cpus` | `1` | Processors fitted. 2 only on the Octane; see [its guide](docs/Octane/multiprocessor.md). |

### [graphics]
Expand Down Expand Up @@ -297,7 +297,7 @@ Omit `[nfs]` to disable the share; the default forward list is empty.

| Key | Default | Values and behavior |
|---|---|---|
| `clock.fixed_mhz` | `33 on IP22/IP24; 97.5 on IP28; 90 on the O2 when unset` | CP0 Count MHz; IRIX's CPU inventory and the O2's PROM report twice this rate. |
| `clock.fixed_mhz` | `half the part's clock (75 on an R4400 Indy)` | CP0 Count MHz; IRIX's CPU inventory and the O2's PROM report twice this rate. |

### [rtc_offset]

Expand Down Expand Up @@ -435,7 +435,7 @@ iris-gui does not parse this standalone option set; use its named-machine UI.
| `--validate` | Check the configuration (parse, settings, files, directories, ports) without starting the machine; exit 0 or 1. See [HELP.md](HELP.md#checking-a-configuration). |
| `--list-net-interfaces` | Print the host network interfaces libpcap can bridge onto, then exit. Requires a build with --features pcap. |
| `--no-scsi-deferred-int` | Disable deferred SCSI status interrupts (default: enabled for OpenBSD/NetBSD compatibility). |
| `--cpu` | Emulated CPU: `r4400` (default), `r5000`, or `r10000`. Overrides `[machine] cpu`. |
| `--cpu` | Emulated CPU: a family (`r4400`, `r5000`, `r10000`, `r12000`, `r14000`) or a part (`r14000_600`) the machine takes. Overrides `[machine] cpu`. |
| `--graphics` | Graphics board: `newport` (default), `xz`, `extreme`, `solidimpact`, `highimpact`, `maximpact` (or `impact:solid`, `impact:high`, `impact:max`), `v6`, `v8`, `v10`, `v12` (`vpro:v12` and so on, Octane only). |
| `--raster` | VPro: `cpu` (default) or `wgpu`, the raster unit on the host GPU (`[graphics] raster`; needs a build with the `wgpu` feature). |
| `--renderer` | What draws the window: `gl` (default) or `wgpu` (`renderer`; needs a build with the `wgpu` feature). |
Expand Down
9 changes: 5 additions & 4 deletions HACKING.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ Other documents:

IRIS emulates five SGI workstations: the Indy (IP24), the Indigo2 (IP22), the
Indigo2 IMPACT (IP28), the O2 (IP32) and the Octane (IP30). The CPU is an
R4400, R5000 or R10000, chosen at runtime (the Octane takes the R10000 only).
R4400, R5000, R10000, R12000 or R14000, chosen at runtime from the parts the
machine shipped with (`src/cpu/parts.rs`).
Graphics is Newport (REX3), GR2 (XZ/Extreme) or IMPACT on the Indy and
Indigo2, GBE on the O2 and Solid IMPACT on the Octane. It boots the real PROMs
and IRIX 5.3 and 6.5 to a desktop with networking.
Expand Down Expand Up @@ -271,8 +272,8 @@ in [docs/interrupt_map.md](docs/interrupt_map.md).

### Time

CP0 Count is derived from host wall-clock time at a fixed rate (33 MHz on
IP22/IP24, 97.5 MHz on IP28; `[clock] fixed_mhz` overrides). The Compare
CP0 Count is derived from host wall-clock time at a fixed rate (half the part's
clock, `Part::count_hz`: 75 MHz on the Indy R4400, 97.5 MHz on IP28; `[clock] fixed_mhz` overrides). The Compare
interrupt and other periodic device events come from host timers
(`src/hptimer.rs`), not from counting instructions. A guest that runs faster
or slower than real hardware sees the same time passing. `--features
Expand Down Expand Up @@ -371,7 +372,7 @@ consumer thread never takes `rec`.
handler sets the PC itself, including delay slots.
- The CPU model is the `CpuModel` trait (`MIPS4`, `PRID`, `FIR`,
`TLB_ENTRIES`, ...), implemented by each cache model. The executor is
monomorphised over it, so all three CPUs are in every binary with no
monomorphised over it, so every CPU is in every binary with no
per-model branch on the hot path. `Machine::new` picks one from `[machine]
cpu`.
- With `opcodefusion` (implied by `lightning`), the interpreter executes
Expand Down
12 changes: 6 additions & 6 deletions HELP.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ host. `lightning` builds and the JIT stack (`--features jitv2,gpujit`) give
higher MIPS; the hinv MHz string stays the same.

The guest's MHz comes from the CP0 Count rate, which is fixed: Count ticks at
33 MHz on IP22/IP24 (66 MHz CPU inventory) or 97.5 MHz on IP28
(195 MHz CPU inventory), anchored to host wall-clock time. There is
half the configured part's clock (75 MHz for the 150 MHz R4400 of an Indy or
Indigo2, 97.5 MHz for the 195 MHz R10000 of an IP28), anchored to host wall-clock time. There is
no calibration or inference. Override it with `[clock] fixed_mhz` or
`--clock-fixed-mhz` if a guest needs something else.

Expand Down Expand Up @@ -630,7 +630,7 @@ scsi_deferred_int = true # needed by OpenBSD/NetBSD; see --no-scsi-deferr

[machine]
profile = "indy_ip24" # "indigo2_ip22" (--ip22), "indigo2_ip28", or "o2_ip32" (an [o2] section: docs/o2-ip32.md); --machine NAME picks any
cpu = "r4400" # "r5000" or "r10000" (--cpu); use R10000 on IP28
cpu = "r4400" # "r5000" (--cpu); IP28: "r10000", Octane: r10000/r12000/r14000, O2: r5000/r10000/r12000; or a part, "r14000_600"
# cpus = 2 # Octane only: a second processor (docs/Octane/multiprocessor.md)

[graphics]
Expand All @@ -643,7 +643,7 @@ resolution = "guest" # or "1024x768", "1280x960", "1280x1024"
# gpu_backend = "auto" # with raster = "wgpu": "vulkan", "metal", "dx12" or "gl"

[clock]
# fixed_mhz = 33 # Count MHz: default 33 on IP22/IP24, 97.5 on IP28
# fixed_mhz = 33 # Count MHz: default half the part's clock: 75 on the Indy and Indigo2 R4400, 97.5 on IP28

# [rtc_offset] # guest clock start, relative to host time (all signed)
# years = -18 # years/months step the calendar (Mar 31 -1 month = Feb 28/29)
Expand Down Expand Up @@ -801,9 +801,9 @@ Configuration
--machine <NAME> Machine to emulate (a [machine] profile name); `help` lists them
--ip22 Same as --machine indigo2_ip22
--graphics <BOARD> newport, xz, extreme, solidimpact, highimpact, maximpact, v6, v8, v10, v12
--cpu <MODEL> r4400 (default), r5000, or r10000
--cpu <MODEL> r4400 (default), r5000, r10000, r12000 or r14000, as the machine allows
--bank0..--bank3 <MB> RAM bank sizes (0/8/16/32/64/128; IP28: also 256/512)
--clock-fixed-mhz <MHZ> CP0 Count frequency (IP22/IP24: 33; IP28: 97.5)
--clock-fixed-mhz <MHZ> CP0 Count frequency (default: half the part's clock, 75 for an Indy R4400)
Storage
--scsi1/2/3/7 <FILE> Hard disk image at that SCSI ID
Expand Down
4 changes: 4 additions & 0 deletions bench/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,10 @@ and the normal mode for speed. The result is labelled
| `r5000-jitv2` | `jitv2` | `r5000` |
| `r4400-lightning` | `lightning` | `r4400` |
| `r4400-jitv2-lightning` | `jitv2,lightning` | `r4400` |
| `r10000-interp`, `r12000-interp`, `r14000-interp` | (default) | `r10000_195`, `r12000_360`, `r14000_600` |
The R10000 family always runs the shadow caches. The suite's Indy has the test
device on, which takes any part; a product Indy takes only the R4400 and R5000.
Each build is copied to `bench/build/iris-<features>` before the next one starts —
the next `cargo build` overwrites `target/release/iris`, and a matrix that races
Expand Down
1 change: 1 addition & 0 deletions docs/indigo2-ip28.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

IP28 pairs the Indigo2 fullhouse devices with an R10000 CPU and IMPACT graphics.
The same binary supports IP24, IP22, and IP28; no `ip28` Cargo feature is needed.
The profile takes only the R10000, and the Indy and IP22 profiles only the R4400 or R5000.
IRIX 6.5 desktop boot and a two-bank 1 GB configuration have been recorded in
the repository's validation notes. Device and graphics coverage is still evolving.

Expand Down
16 changes: 9 additions & 7 deletions docs/o2-ip32.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
The O2 is SGI's unified-memory workstation: CRIME (the memory controller and
rendering engine), MACE (the I/O chip: PCI, Ethernet, serial ports, PS/2,
audio, the clocks) and GBE (the display engine, which scans the frame buffer
out of main memory). IRIS emulates it with an R10000 or an R5000, chosen at run
time like the other machines.
out of main memory). IRIS emulates it with an R5000, R10000 or R12000, chosen at
run time like the other machines.

It runs IRIX 6.5 (tested with 6.5.22) to the desktop, with networking, audio,
SCSI disks and CD-ROMs, X and OpenGL through the CRIME rendering engine, and
Expand All @@ -28,7 +28,7 @@ serial_log = "serial.log"

[machine]
profile = "o2_ip32"
cpu = "r10000" # or "r5000"
cpu = "r10000" # or "r5000" or "r12000"

[o2]
control_port = 2293
Expand Down Expand Up @@ -65,14 +65,16 @@ in the file to silence the note.

## CPU, memory and clock

- **R10000 and R5000** both run the shadow cache model that IP28 uses, from
- **R5000, R10000 and R12000** all run the shadow cache model that IP28 uses, from
reset: loads and stores go straight to memory. The PROM tests physical page
0 uncached while its stack sits in cache tags for that same page, so while
those tags stand the bus answers for the page from a separate 4 KB page.
- Linux supports only R5000-class O2s.
- `[clock] fixed_mhz` is CP0 Count, 90 MHz unless set; the PROM measures and
reports twice it as the CPU clock. R10000 O2s shipped at 175 and 195 MHz
(87.5 and 97.5), R5000s at 180 to 300.
- `[clock] fixed_mhz` is CP0 Count, half the part's clock unless set (90 MHz for
the R5000); the PROM measures and reports twice it as the CPU clock. `r10000`
is the rev 3.4 250 MHz part and `r12000` the rev 3.5 400 MHz part with a 2 MB
secondary cache. Both have 64-byte secondary lines, because the PROM fails with
128-byte ones.
- `banks` is the kit in each of the four DIMM pairs from A: 32, 64, 128 or
256 MB each, largest first, up to 1 GB. The default `[128, 128]` is 256 MB.
IRIX boots with any of them, from a single 32 MB kit up. NetBSD's 32-bit
Expand Down
8 changes: 5 additions & 3 deletions docs/octane-ip30.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,11 @@ overlay = true
```

Paths are relative to the directory iris runs in. Every key is listed in
[FEATURES.md](../FEATURES.md). `machine.cpu` must be `r10000`. `[clock]
fixed_mhz` sets CP0 Count; unset it is 97.5 MHz, half of the R10000's
195 MHz pipeline clock.
[FEATURES.md](../FEATURES.md). `machine.cpu` is `r10000` (revision 2.7),
`r12000` (revision 3.5, 2 MB secondary cache) or `r14000` (revision 2.4, 2 MB).
`[clock] fixed_mhz` sets CP0 Count, half the pipeline clock. Unset it is
97.5 MHz for the 195 MHz R10000, 180 MHz for a 360 MHz R12000 and 300 MHz for a
600 MHz R14000.

## PROM and flash

Expand Down
8 changes: 4 additions & 4 deletions iris-gui/src/bench_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ pub struct BenchState {
last: Option<Result<Box<Run>, String>>,
quick: bool,
/// Which CPU to benchmark. Runtime config, so this needs no separate build.
cpu: iris::config::CpuModel,
cpu: &'static iris::cpu::parts::Part,
/// Parsed once. Normally empty — see `iris::bench_report::bundled_reference`.
reference: Option<ReferenceTable>,
dev: DevRunner,
Expand All @@ -62,7 +62,7 @@ impl Default for BenchState {
// number, and is required before a result can go in the reference
// table.
quick: true,
cpu: iris::config::CpuModel::default(),
cpu: &iris::cpu::parts::R4400_150,
reference: None,
dev: DevRunner::default(),
}
Expand Down Expand Up @@ -102,7 +102,7 @@ impl BenchState {
self.live.is_some() || self.dev.is_running()
}

fn start(&mut self, quick: bool, cpu: iris::config::CpuModel) {
fn start(&mut self, quick: bool, cpu: &'static iris::cpu::parts::Part) {
if self.is_running() { return; }

let lines = Arc::new(Mutex::new(Vec::new()));
Expand Down Expand Up @@ -240,7 +240,7 @@ fn controls(ui: &mut Ui, st: &mut BenchState, machine_running: bool) {
egui::ComboBox::from_id_salt("bench_cpu")
.selected_text(st.cpu.label())
.show_ui(ui, |ui| {
for m in iris::config::CpuModel::ALL {
for &m in iris::bench_runner::BENCH_CPUS {
ui.selectable_value(&mut st.cpu, m, m.label());
}
})
Expand Down
Loading
Loading