Commit Graph
151 Commits
Author SHA1 Message Date
joevt 320688dee7 ppcmmu: Fix spelling. 2026-09-22 20:19:00 -07:00
Mihai Parparita 1a0439a871 ppcmmu: Flush all PAT-derived TLB entries for the tlbie instruction
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@3dcfb74fd4) 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 #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
2026-09-16 18:33:16 -07:00
Mihai Parparita 13ccd42e16 ppcmmu: Track translated entries for invalidation
XNU frequently changes BAT and PAT mappings for physical-memory access.
Each  resulting context synchronization can walk tens of thousands of TLB
entries, which consumes a lot of time.

Record the instruction and data TLB slots populated by BAT or PAT and
invalidate only those slots. Pending invalidations are coalesced by source,
and BAT updates cover PAT-derived entries because a new BAT can shadow a page
mapping.

Saves another 0.7 secondss in the time it takes to boot Mac OS X 10.3 to
the WindowServer (compared to the generational PAT invalidation).
2026-08-20 22:54:26 -07:00
Mihai Parparita 855f43c2eb ppcmmu: Revert generational PAT invalidation
PAT generation counters make invalidation constant-time by adding a
generation check to every TLB lookup, but they added a per-access overhead
to compare generation counters. I am swithcing to an alternate approach
(explicitly tracking populated entries, which can also be used for
BAT-derived entries), and am removing this first to make that diff
easier to read.

This logically reverts the work from #199 (the TLB helper refactoring
from #203 prevents a mechanical revert).
2026-08-20 22:54:26 -07:00
Mihai Parparita 253844cec5 ppcmmu: Add helpers for repeated TLB operations
Helps a bit with some of the code duplication introduced in #203.
2026-08-14 19:26:02 -07:00
Mihai Parparita 8f6274ed8a ppcmmu: Ignore dcbz for MMIO regions
The ATI drivers uses dcbz to simulate a write-combining buffer when
sending HOST_DATA payloads.

The intent is something like this (on real hardware):

```
dcbz:
    cache line = [0, 0, 0, 0, 0, 0, 0, 0]
    ATI sees nothing

following stores:
    cache line = [A, B, C, D, E, F, G, H]
    ATI still sees nothing

dcbf or eviction:
    write back [A, B, C, D, E, F, G, H]
    ATI receives one completed cache line
```

With our previous cacheless implementation, the behavior was more like this:
```
dcbz:
    ATI immediately receives [0, 0, 0, 0, 0, 0, 0, 0]

following stores:
    ATI then receives [A, B, C, D, E, F, G, H]

dcbf:
    no-op
```

The zero-ed out values have side effects (32 pixels of black being
written), so the intermediate state was visible.

The truly correct fix is to fully model the data cache, and do an
eventual write back of the modified cache lines with their final values,
but that is very invasive (and likely to be slow).

We instead just make `dcbz` a no-op for MMIO regions, which lets us
avoid that intermediate state and unintended side effects.
2026-08-08 06:46:01 -07:00
joevt eade7a0a30 ppcmmu: Fix indenting. 2026-08-07 06:47:41 -07:00
Mihai Parparita 2c7a7c5c36 ppcmmu: Use generational flush for PAT entries
We end up flushing all entries very frequently (hundreds of thousands of times
during Mac OS X boot), and were spending a lot of time in `tlb_flush_entries`
walking through the array. We can instead store a generation counter and
make invalidation be a simple increment. This does make validity checks slightly
more expensive, but it appears to be a net win. On my machine it takes booting
the Mac OS X public meta to the Finder from ~58 seconds to ~35 seconds.
2026-08-06 07:33:54 -07:00
Mihai Parparita 1b0ac89674 ppcmmu: Move TLB internals into implementation
`TLBEntry` and its cache constants and flags are used exclusively by
ppcmmu.cpp. Keep them out of the public MMU header so future TLB changes
do not expand its interface.

This required a small fix in dbdma.cpp since it was implicitly relying on
an include that we removed.

Also declare `gTLBFlush*` variables as static to make it explicit that we
don't expect them to be accessed outside of ppcmmu.cpp.
2026-08-06 07:33:54 -07:00
Mihai Parparita 172efccd1b cpu: remove unused global variables (#197)
Last glob_bb_start_la use was removed in d83fdd8866.

Last last_read_area, last_write_area, and last_exec_area uses were removed
in c9d4cc3321.
2026-08-05 18:43:25 -07:00
Maxim Poliakovski 0e03cac082 Move memaccess.h to core/* 2026-06-07 20:32:46 +02:00
joevt 54a1eb49f7 ppcmmu: Add a debug version of mmu_map_dma_mem.
This is for the DPPC debugger, not for debugging DPPC.
2026-06-02 20:34:26 -07:00
joevt fe80d14e8a ppcmmu: uintptr_t (not size_t) for host pointers. 2026-05-29 06:51:32 -07:00
Rairii 09c1248be7 CPU and memory controller endian changes.
===============
Rairii changes:

memctrlbase: The memory controller may have an endian swap mode.
mpc106: Only mmio regions need endian swap and only if PCIR_LE_MODE is
set.

videoctrl: Add framebuffer_in_main_memory flag. Use needs_swap_endian.

debugger: Fix disasm for little endian mode.

ppcmmu: little endian mode requires munging of the data and instruction
addresses, affecting the 3 least significant bits.

ppcexec: pc_real is always recalculated during little endian mode
because instructions are swapped every 8 bytes (due to the address
munging).

==============
joevt changes:

Add SUPPORTS_MEMORY_CTRL_ENDIAN_MODE for memory controller.
Use cmake -DDPPC_SUPPORT_PPC_LE=ON to enable.

Add SUPPORTS_PPC_LITTLE_ENDIAN_MODE for CPU.
Use cmake -DDPPC_SUPPORT_MEM_LE=ON to enable.

Add ppc_change_endian to handle endian switch for MPC601 (uses HID0
instead of MSR) and later PPC CPUs.

Add is_LE flag to ppc_state to indicate little endian mode for all
processor versions.

Create separate ppc_exec_inner template functions for little and big
endian.

Switch endian mode in the ppc_exec outer functions when power_off_reason
is po_endian_switch.

Since MPC601 doesn't have ILE and LE bits, remove that code for that
CPU.

videoctrl: Uses templated methods. See next commit for a fix that this
change introduces.
2026-04-12 10:06:32 -07:00
joevt 7aacd5c703 ppcmmu: Initialize bat structs after bat regs.
Needed for machine restart.
2026-04-11 13:36:58 -07:00
joevt 91f5ccc3f9 ppcmmu: Simplify pteg address calculation.
Maybe the optimizer can do it or maybe not.
2026-03-31 07:39:45 -07:00
dingusdev 213dd4c16e Update copyright info further 2026-01-30 08:12:04 -07:00
Maxim Poliakovski e75ee8d32a Update copyright year. 2026-01-30 12:15:00 +01:00
joevt 1b719f2d8f ppcmmu: Delete blank line. 2025-07-25 07:09:09 -07:00
joevt 1b7ec272d8 ppcmmu: Don't crash on MPC601 DBAT access. 2025-07-25 07:05:41 -07:00
Mihai Parparita 26724feff1 ppcmmu: fix tlb_flush_secondary_entry
It would iterate over all of the entries in the two-way line, but only
check the first one.

Fixes 10.1 kernel panic on boot after c317ed8b42.
2025-07-03 16:31:20 -07:00
joevt 5412fbc198 Remove superfluous semicolons. 2025-06-27 19:01:14 -07:00
Maxim Poliakovski c317ed8b42 ppcmmu: fix TLB invalidation again. 2025-06-17 13:08:31 +02:00
Maxim Poliakovski 101d8aa885 ppcmmu: fix TLB invalidation.
The PowerPC manual says that `tlbie` only considers
bits 4-19 of the EA. Set the mask accordingly.
2025-05-21 18:42:57 +02:00
joevt c6013f076a ppcmmu: Fix DMA for adjacent cross region ranges.
If a DMA range extends beyond the end of a region into a second region of the same type (either RAM or ROM), and the regions are adjacent in both the guest and host address spaces, then allow the DMA to proceed.
2025-04-23 06:32:28 -07:00
joevt ba9bbb32c3 Catch all errors for debug read/write methods. 2025-03-23 16:14:31 -07:00
dingusdev a972bd26f7 Corrected handling of MMU Mode 1 2025-03-02 10:41:42 -07:00
joevt 7b1ea17fb8 ppcmmu: Fix compiler warning. 2024-12-17 18:46:53 -07:00
Maxim Poliakovski aa17bf06de ppcmmu: implement mem_write_dbg method. 2024-11-30 11:55:16 +01:00
Mihai Parparita bf92b04d6c debugger: Use a named constant when we don't have a current instruction 2024-11-29 18:33:22 +01:00
Mihai Parparita 564c43c907 Remove ppc_cur_instruction global variable
Replace it wth an explicit opcode parameter that is passed around. That
is both slightly easier to reason about (to trace where it comes from)
and slightly faster, since it can be read from a register.

On my machine takes booting to "Welcome to Macintosh" being output in
a verbose boot of Mac OS X 10.2.8 from 31.8s to 30.6s (average of 5
runs, measured using deterministic mode and looking at when execution
reaches PC 0x90004a88).
2024-11-28 23:41:38 +01:00
dingusdev 9d9e826bb3 More code clean-up 2024-09-08 13:19:07 -07:00
Rairii 8cc67b09c2 ppcmmu: Different expressions. 2024-09-03 06:09:45 -07:00
Mihai Parparita 76824fb602 ppcmmu: skip over mode 1 entries when doing PAT flushes
Mode 1 contains real addressing mode entries, which by definition cannot
be using segment registers. By skipping over them, we can shave off a
couple of seconds from the 10.2 boot time.
2024-07-31 23:08:36 -07:00
dingusdev 606c9dd9a8 More compiler warning fixes 2024-06-24 19:40:20 -07:00
joevt 30afcb6ddc ppcmmu: Allow map dma for last byte of region.
cur_dma_rgn->end is the last byte of a region. It is not the byte after the region. Therefore, subtract 1 from size before doing compare.

Also add more detail to the abort messages.
2024-04-24 06:50:53 -07:00
joevt ad45ce8499 ppcmmu: Make dummy pages two pages.
In case we need a write to span a page boundary.
2024-04-24 06:49:11 -07:00
joevt a8023bb41b ppcmmu: Remove last_dma_area.
DMA may happen on CPU and audio threads but update of last_dma_area is not thread safe.
2024-04-21 09:13:42 -07:00
dingusdev 2c94cfee03 Removing currently unneeded functions 2024-04-09 18:34:36 -07:00
joevt 3c16870f86 ppcmmu: Replace defines.
They may interfere with system headers.
2024-04-09 07:57:48 -07:00
joevt 9ed1a118e6 ppcmmu: Check sizeof(T) explicitly.
I don't know if the compiler is smart enough to figure out that ((guest_va & 0xFFF) + sizeof(T)) > 0x1000) is always false when sizeof(T) == 1 so we'll add a check for sizeof(T) > 1.
2024-04-07 08:59:05 -07:00
joevt d9b02ecd8d ppcmmu: Check 8 byte alignment spanning pages. 2024-03-28 07:53:03 -07:00
joevt c9d4cc3321 ppcmmu: Remove old and slow code. 2024-03-27 20:13:45 -07:00
joevt 0f8a464157 ppcmmu: Use MSR enums for calculating mmu_mode. 2024-03-27 18:44:59 -07:00
joevt e4a675babb ppcmmu: Remove line feed from log messages. 2024-03-27 18:44:42 -07:00
joevt bc5fd44172 ppcmmu: Don't log mmu_mode 1. 2024-03-24 18:52:49 -07:00
joevt bc5153dd4a ppcmmu: Make sure dummy page is 8 byte aligned. 2024-03-13 21:45:56 -07:00
joevt aed74479fd ppcmmu: Handle undefined mmu mode. 2024-03-13 21:38:26 -07:00
Mihai Parparita c7d2eb87ac Initialize MMU recently used regions in ppc_mmu_init
More encapsulated and allows re-initialization.
2024-03-07 23:31:56 -08:00
joevt de73a36399 ppcmmu: Move defines to the top. 2024-03-02 07:58:25 -07:00