Skip to content

ppcmmu: Flush all PAT-derived TLB entries for the tlbie instruction - #224

Merged
dingusdev merged 1 commit into
dingusdev:masterfrom
mihaip:upstream-750-tlb-flush
Sep 17, 2026
Merged

dingusdev merged 1 commit into
dingusdev:masterfrom
mihaip:upstream-750-tlb-flush

Conversation

@mihaip

@mihaip mihaip commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

This fixes booting Mac OS 8.6 hanging at the Happy Mac on the iMac G3. During boot, as part of installing the nanokernel, the OS attempts to do a full TLB flush via a series of tlbie instructions. We were trying to respect the effective address that's specified in the instruction, but the semantics of how it should be interpreted are different on the 750 CPU - the user manual says:

The tlbie instruction invalidates all TLB entries indexed by the EA, and operates on both the instruction and data TLBs simultaneously invalidating four TLB entries. The index corresponds to bits 14-19 of the EA.

We were not respecting the bits 14-19 part (TLB_VPS_MASK matched bits 4-19), and thus not matching all expected entries. The stale entries would remain, leading to unexpected behavior.

Rather than trying to more precisely model the 750 behavior, we instead flush all PAT-derived TLB entries. This matches QEMU's approach (see qemu/qemu@3dcfb74) and is allowed by the PowerPC specification:

For example, the tlbie instruction may be implemented to purge all TLB entries in a congruence class (that is, all TLB entries indexed by the specified effective address which can include corresponding entries in data and instruction TLBs) or the entire TLB.

As of #219 a full flush is not that expensive, thus this does not materially affect performance. The goal of the guest OS is a full TLB flush anyway (hence the sweep of tlbie instructions), so we don't end up doing too many extra lookups after they're done.

For #184

This fixes booting Mac OS 8.6 hanging at the Happy Mac on the iMac G3.
During boot, as part of installing the nanokernel, the OS attempts to do
a full TLB flush via a series of `tlbie` instructions. We were trying to
respect the effective address that's specified in the instruction, but
the semantics of how it should be interpreted are different on the 750
CPU - the [user manual](https://www.nxp.com/docs/en/reference-manual/MPC750UM.pdf)
says:

> The `tlbie` instruction invalidates all TLB entries indexed by the EA,
> and operates on both the instruction and data TLBs simultaneously
> invalidating four TLB entries. The index corresponds to bits 14-19 of the EA.

We were not respecting the bits 14-19 part (`TLB_VPS_MASK` matched bits
4-19), and thus not matching all expected entries. The stale entries
would remain, leading to unexpected behavior.

Rather than trying to more precisely model the 750 behavior, we instead
flush all PAT-derived TLB entries. This matches QEMU's approach (see
qemu/qemu@3dcfb74) and is allowed by
[the PowerPC specification](http://refspecs.linux-foundation.org/PPC_hrm.2005mar31.pdf):

> For example, the tlbie instruction may be implemented to purge all TLB
> entries in a congruence class (that is, all TLB entries indexed by the
> specified effective address which can include corresponding entries in
> data and instruction TLBs) **or the entire TLB**.

As of dingusdev#219 a full flush is not that expensive, thus this does not
materially affect performance. The goal of the guest OS is a full TLB
flush anyway (hence the sweep of `tlbie` instructions), so we don't end
up doing too many extra lookups after they're done.

For dingusdev#184
mihaip added a commit to mihaip/infinite-mac that referenced this pull request Sep 16, 2026
Many of our OS images were generated via SheepShaver emulating an OldWorld machine,
thus the Mac OS ROM file was not necessarily present or the expected version.

This matters more when trying to boot a NewWorld machine like the iMac under
DingusPPC. Specifically, this was discovered when validating the fix from
dingusdev/dingusppc#224 - the 8.6 boot would hang during the progress bar
step, and this was traced due to a mismatched ROM file version (the 8.6 install
CD was fine).

Update the images to match the ones on the install CD and/or the table from the
KB article: https://web.archive.org/web/20020620095518/http://docs.info.apple.com:80/article.html?artnum=24965
(found via https://www.savagetaylor.com/2023/12/20/apples-technical-information-library-til/)

- Mac OS 8.6: 1.4 (had 1.1.2)
- Mac OS 9.0: 3.0 (had nothing)
- Mac OS 9.0.4: 3.7 (had nothing)
- Mac OS 9.1: 6.1 (had nothing)

The Mac OS 9.2.2 image already had ROM version 8.7, which presumably is correct.

Also updates the prefetch chunks to match current disk images.
@dingusdev
dingusdev merged commit 1a0439a into dingusdev:master Sep 17, 2026
7 checks passed
@mihaip
mihaip deleted the upstream-750-tlb-flush branch September 17, 2026 02:21
mihaip added a commit to mihaip/infinite-mac that referenced this pull request Sep 17, 2026
Includes dingusdev/dingusppc#224 which fixes the iMac G3 booting 8.6.

For #219
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