Skip to content

ppc: Model configurable CPU frequencies - #210

Draft
mihaip wants to merge 2 commits into
dingusdev:masterfrom
mihaip:codex/tiger
Draft

ppc: Model configurable CPU frequencies#210
mihaip wants to merge 2 commits into
dingusdev:masterfrom
mihaip:codex/tiger

Conversation

@mihaip

@mihaip mihaip commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Virtual time previously advanced by a fixed 16 ns per interpreted instruction, making every CPU behave like the legacy 62.5 MHz model regardless of the selected machine. G3 guests also received ad hoc HID1 values from individual machine implementations, while Gazelle supported several frequencies that could not share that logic.

Require each machine to provide its hardware-appropriate bus, core, and timebase clocks through one PPC_CPU_Config configuration object. We can then derive things from it (e.g. supported MPC603ev and MPC750 HID1 PLL encodings). We can also populate the include_601 global based on version instead of a separate flag.

To model time with more flexibility, we now use 60.4 fixed-point nanoseconds for instruction timing. This lets us have a broad set of frequencies and still support running the CPU for ~35 years of virtual time before it overflows.

This results in two emulation accuracy improvements:

  • Tiger successfully gets to the Finder. The virtual time we were exposing to the guest was advancing too quickly, preventing loginwindow from connecting before WindowServer's internal five-second no-client timer expired. The server then exited normally, loginwindow aborted when it could not establish its CoreGraphics connection, and we remained stuck at the last textual output from a verbose boot ("Waiting for IFC").
  • Animations are now more accurate (e.g. Mac OS X dock icon bouncing is no longer too fast on a G3)

This behavior is opt-in, configured by the --cpu-timing=per-machine flag. This way host machines that cannot keep up with the new timing are not forced to use it, since that makes the perceived performance worse (main difference from the version in #209).

To also make the new variable access in the ppc_exec_inner loop be net-neutral in terms of x86-64 register allocation, there is a small optimization to remove the unnecessary page_start variable.

For #194

mihaip added 2 commits August 14, 2026 14:28
The `page_start` variable is not needed, we can get the same information
(for the end of execution block comparison) from `eb_end`.

This keeps one fewer value live across each opcode invocation. On
x86-64 it removes one register spill/reload pair from the execution loop.
Virtual time previously advanced by a fixed 16 ns per interpreted
instruction, making every CPU behave like the legacy 62.5 MHz model
regardless of the selected machine. G3 guests also received ad hoc HID1
values from individual machine implementations, while Gazelle supported
several frequencies that could not share that logic.

Require each machine to provide its hardware-appropriate bus, core, and
timebase clocks through one `PPC_CPU_Config` configuration object. We can then
derive things from it (e.g. supported MPC603ev and MPC750 HID1 PLL encodings).
We can also populate the `include_601` global based on `version` instead of a
separate flag.

To model time with more flexibility, we now use 60.4 fixed-point nanoseconds for
instruction timing. This lets us have a broad set of frequencies and still
support running the CPU for ~35 years of virtual time before it overflows.

This results in two emulation accuracy improvements:
- Tiger successfully gets to the Finder. The virtual time we were exposing to
  the guest was advancing too quickly, preventing loginwindow from connecting
  before WindowServer's internal five-second no-client timer expired.
  The server then exited normally,  loginwindow aborted when it could not
  establish its CoreGraphics connection, and we remained stuck at the last
  textual output from a verbose boot ("Waiting for IFC").
- Animations are now more accurate (e.g. Mac OS X dock icon bouncing is no
  longer too fast on a G3)

This behavior is opt-in, configured by the `--cpu-timing=per-machine`
flag. This way host machines that cannot keep up with the new timing are
not forced to use it, since that makes the perceived performance worse.
@mihaip
mihaip marked this pull request as draft August 15, 2026 16:40
@mihaip

mihaip commented Aug 15, 2026

Copy link
Copy Markdown
Contributor Author

(converting to draft, will think if there's a less invasive way of getting Tiger to boot)

@joevt

joevt commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

What's wrong with the proposed changes?
Post a benchmark to show the difference in performance?
Use a time increment that is equal to the original instruction period to compare?

@joevt

joevt commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

A g_instruction_period of 256 should match the original icnt_factor of 4.

@mihaip

mihaip commented Aug 15, 2026

Copy link
Copy Markdown
Contributor Author

@joevt this adds some complexity (and a new execution mode), hence my second thoughts.

@joevt

joevt commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

So it's not a performance issue?

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