StarOS MMU-001 F1: optional ARM926 MMU aborts (--mmu-faults) and panic words #1

Closed
Yaya48 wants to merge 0 commits from staros/mmu-faults into master
pull from: staros/mmu-faults
Owner

StarOS MMU-001 F1, authorised by the maintainer: the ARM926 MMU faults, off by default and enabled only by --mmu-faults. The interpreter and the JIT must pass the same tests, and the IOS LLE behaviour must not change silently.

Commits

  1. 9b493a1e16 IOS LLE: optional ARM926 MMU aborts and CP15 privilege. ARMCore::SetMMUFaultsEnabled turns on:
    • Faults from the descriptors: translation (0x5 section, 0x7 page), domain (0x9, 0xb) and permission (0xd, 0xf).
    • The DACR: no access and the reserved value fault; Manager skips the AP check.
    • AP, with the control register's S and R bits.
    • ARMv5 has no XN: a fetch needs read permission.
    • Data aborts: vector 0x10, LR = instruction + 8, FSR and FAR (the FAR holds the MVA).
    • Prefetch aborts: vector 0x0c, LR + 4, IFSR (c5, opcode_2 1). The FAR is not changed.
    • Alignment faults when control bit A is set.
    • Base-restored aborts: the instruction's register results are undone, and words stored before the fault stay written.
    • LDRT/STRT check User permissions in any mode.
    • The TLB keeps each entry's domain and AP. A faulting walk is never cached. A c8 single-entry operation drops only the page that maps the MVA, so an entry stays stale until the guest invalidates it.
    • CP15 from User mode is undefined.
  2. cdec826bb8 StarletBootstrapProbe: --mmu-faults.
  3. 612cab7b30 StarletBootstrapProbe: reports StarOS's panic words (__panic_state, __panic_code). They are optional in LoadBootstrapELF, but both or neither, and must lie in the data segment. --expect-panic passes on state 1 (a REV:PANIC line still works).
  4. 2bae49bdad IOS LLE: the ARM926 TLB is unified (review). Two comments said the I and D TLBs were separate. They now name the real differences of the software TLB: capacity and replacement (direct-mapped, 4096 granules of 1 KiB), and lockdown (c10), which is not modelled. No code change.

The JIT with the option on:

  • every block entry goes through C++, which checks the fetch under the current mode and DACR;
  • only instructions that touch neither memory, CP15, the PSRs nor the exception model run natively;
  • every other instruction goes through the interpreter fallback, which ends the block.

No silent change to IOS LLE

With the option off:

  • fault descriptors keep their identity fallback;
  • the savestate format is unchanged (the option and the IFSR are not serialized);
  • idle-loop fast-forwarding, the native dispatcher and the JIT's native memory paths are unchanged;
  • the only added work is one abort flag that the data accessors read and that stays clear.

DisabledFaultsKeepTheIdentityFallbackAndUserCP15 checks this in both engines.

Evidence (Windows x64, MSVC 19.51, Release)

  • 20 StarletARMCoreMMUFaults tests, each run in the interpreter and the JIT: PASS.
  • 10 mutants of the fault model, each caught by 2 to 10 tests: AP, DACR, faulting walk, register restore, prefetch abort, single-entry invalidation, FAR on prefetch, user CP15, the JIT's entry check, the JIT's native memory paths.
  • Full tests.exe: 1559 tests, 1554 passed, 0 failed, 5 skipped (the StarletEthernetNAT tests, which depend on the environment, as before).
  • Provenance probe built by StarOS tools/dolphin/build_probe.py from 612cab7b308f (sha256 21e888de…), then from 2bae49bdad66, with a clean checkout: StarletBootstrapProbe.exe sha256 403ac3a28d15277def638651c7fbaf39949ce9a763539e19b11dfcd6c59a1a16. Starlet and loader tests (174) pass again at 2bae49bdad.
  • StarOS M1 scenarios with this probe (reports lle-20261013T193254Z and, at 2bae49bdad, lle-20261013T201842Z): trace, stderr, exit status and final position are identical to the f9193539 probe on the same image. With --mmu-faults the output is identical too, instruction counts included (the M1 image runs with the MMU off and A clear).

Limits

  • TLB: unified, as on the ARM926EJ-S, but with a different capacity and replacement, and without lockdown (c10 ignored). A c1 write still flushes it, which hardware does not do.
  • Caches and timing are not modelled.
  • In a coarse table, a tiny-page descriptor faults (fail-closed).
  • For an alignment or section translation fault, the FSR domain field is written as 0 (not valid on hardware).

Merge: fast-forward master to 2bae49bdad once approved. No merge commit; master stays linear.

StarOS MMU-001 F1, authorised by the maintainer: the ARM926 MMU faults, off by default and enabled only by `--mmu-faults`. The interpreter and the JIT must pass the same tests, and the IOS LLE behaviour must not change silently. ## Commits 1. `9b493a1e16` IOS LLE: optional ARM926 MMU aborts and CP15 privilege. `ARMCore::SetMMUFaultsEnabled` turns on: - Faults from the descriptors: translation (0x5 section, 0x7 page), domain (0x9, 0xb) and permission (0xd, 0xf). - The DACR: no access and the reserved value fault; Manager skips the AP check. - AP, with the control register's S and R bits. - ARMv5 has no XN: a fetch needs read permission. - Data aborts: vector 0x10, LR = instruction + 8, FSR and FAR (the FAR holds the MVA). - Prefetch aborts: vector 0x0c, LR + 4, IFSR (c5, opcode_2 1). The FAR is not changed. - Alignment faults when control bit A is set. - Base-restored aborts: the instruction's register results are undone, and words stored before the fault stay written. - LDRT/STRT check User permissions in any mode. - The TLB keeps each entry's domain and AP. A faulting walk is never cached. A c8 single-entry operation drops only the page that maps the MVA, so an entry stays stale until the guest invalidates it. - CP15 from User mode is undefined. 2. `cdec826bb8` StarletBootstrapProbe: `--mmu-faults`. 3. `612cab7b30` StarletBootstrapProbe: reports StarOS's panic words (`__panic_state`, `__panic_code`). They are optional in `LoadBootstrapELF`, but both or neither, and must lie in the data segment. `--expect-panic` passes on state 1 (a `REV:PANIC` line still works). 4. `2bae49bdad` IOS LLE: the ARM926 TLB is unified (review). Two comments said the I and D TLBs were separate. They now name the real differences of the software TLB: capacity and replacement (direct-mapped, 4096 granules of 1 KiB), and lockdown (c10), which is not modelled. No code change. The JIT with the option on: - every block entry goes through C++, which checks the fetch under the current mode and DACR; - only instructions that touch neither memory, CP15, the PSRs nor the exception model run natively; - every other instruction goes through the interpreter fallback, which ends the block. ## No silent change to IOS LLE With the option off: - fault descriptors keep their identity fallback; - the savestate format is unchanged (the option and the IFSR are not serialized); - idle-loop fast-forwarding, the native dispatcher and the JIT's native memory paths are unchanged; - the only added work is one abort flag that the data accessors read and that stays clear. `DisabledFaultsKeepTheIdentityFallbackAndUserCP15` checks this in both engines. ## Evidence (Windows x64, MSVC 19.51, Release) - 20 `StarletARMCoreMMUFaults` tests, each run in the interpreter and the JIT: PASS. - 10 mutants of the fault model, each caught by 2 to 10 tests: AP, DACR, faulting walk, register restore, prefetch abort, single-entry invalidation, FAR on prefetch, user CP15, the JIT's entry check, the JIT's native memory paths. - Full `tests.exe`: 1559 tests, 1554 passed, 0 failed, 5 skipped (the `StarletEthernetNAT` tests, which depend on the environment, as before). - Provenance probe built by StarOS `tools/dolphin/build_probe.py` from `612cab7b308f` (sha256 `21e888de…`), then from `2bae49bdad66`, with a clean checkout: `StarletBootstrapProbe.exe` sha256 `403ac3a28d15277def638651c7fbaf39949ce9a763539e19b11dfcd6c59a1a16`. Starlet and loader tests (174) pass again at `2bae49bdad`. - StarOS M1 scenarios with this probe (reports `lle-20261013T193254Z` and, at `2bae49bdad`, `lle-20261013T201842Z`): trace, stderr, exit status and final position are identical to the `f9193539` probe on the same image. With `--mmu-faults` the output is identical too, instruction counts included (the M1 image runs with the MMU off and A clear). ## Limits - TLB: unified, as on the ARM926EJ-S, but with a different capacity and replacement, and without lockdown (c10 ignored). A c1 write still flushes it, which hardware does not do. - Caches and timing are not modelled. - In a coarse table, a tiny-page descriptor faults (fail-closed). - For an alignment or section translation fault, the FSR domain field is written as 0 (not valid on hardware). Merge: fast-forward `master` to `2bae49bdad` once approved. No merge commit; master stays linear.
Yaya48 added 3 commits 2026-10-13 21:33:32 +02:00
ARMCore::SetMMUFaultsEnabled(true) makes the Starlet core deliver the
faults of the ARM926EJ-S MMU instead of the identity fallback:
- translation (section 0x5, page 0x7), domain (0x9, 0xb) and permission
  (0xd, 0xf) faults from the descriptors, the DACR (no access and the
  reserved value fault; manager skips AP) and AP with the S and R bits;
  ARMv5 has no execute permission, so a fetch needs read permission;
- data aborts (vector 0x10, LR = instruction + 8 in both states) set the
  FSR and the FAR (the MVA); prefetch aborts (vector 0x0c, LR + 4) set the
  IFSR (c5 opcode2 1) and leave the FAR unchanged;
- alignment faults (0x1) when control bit A is set;
- base-restored data aborts: the first faulting access ends the
  instruction's bus traffic and its register results are undone; words
  stored before the fault stay written;
- LDRT/STRT/LDRBT/STRBT check User permissions in any mode;
- the TLB keeps each granule's domain and AP, never caches a faulting
  walk, and c8 single-entry operations drop only the page that maps the
  MVA, so an entry stays stale until the guest invalidates it;
- MRC/MCR to CP15 from User mode is an undefined instruction.

The JIT stays usable: with the option on, every block entry goes through
C++, which checks the fetch under the current mode and DACR, and only
instructions that touch neither memory, CP15, the PSRs nor the exception
model run natively; the rest use the interpreter.

Off by default. The IOS LLE path keeps its identity fallback, its
savestate format (the option and the IFSR are not serialized) and its
idle-loop fast-forwarding; the only change there is that the data
accessors read one abort flag that stays clear.

20 StarletARMCoreMMUFaults tests, each run in the interpreter and the
JIT; the existing Starlet tests pass unchanged.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Enables the ARM926 MMU aborts of ARMCore (SetMMUFaultsEnabled) for the
run. Without the option the probe behaves as before.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
StarOS's panic path (ADR-0014 R6) writes no trace line: it sets the guard
word __panic_state, stores __panic_code and halts. LoadBootstrapELF now
returns both symbols when an image has them (optional, but both or
neither, as words of the data segment), and the probe stops a run whose
guard is set: it prints the trace published so far and
"Starlet panic state <n> code <n>", and passes --expect-panic when the
state is 1. Images without these symbols (StarletOS) load and run as
before; a REV:PANIC trace line still satisfies --expect-panic.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Yaya48 added 1 commit 2026-10-13 22:05:52 +02:00
The ARM926EJ-S has one TLB for instructions and data, with lockdown
entries that whole-TLB invalidation preserves. Two comments said the
I and D TLBs were separate; they now say what the software TLB really
differs in: capacity and replacement (a direct-mapped cache of 4096
1 KiB granules), and lockdown, which is not modelled (c10 writes are
ignored). No code change.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Yaya48 closed this pull request 2026-10-13 22:37:25 +02:00
Yaya48 deleted branch staros/mmu-faults 2026-10-13 22:37:25 +02:00

Pull request closed

This pull request cannot be reopened because the branch was deleted.
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Yaya48/dolphin#1