Repository navigation
Carve EE invocation stacks from kernel-reserved RAM instead of the top of game RAM - #413
Open
0xLeathery wants to merge 4 commits into
Open
0xLeathery wants to merge 4 commits into
0xLeathery wants to merge 4 commits into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
PS2Runtime::reserveAsyncCallbackStackhands out the 16 KB guest stacks thatEeScheduler::invocationStackTopgives to interrupt handlers, RPC/stream callbacks, HLE calls and exit handlers. It carves them downward from the top of the 32 MB EE RAM (m_asyncCallbackStackTop = PS2_RAM_SIZE, floor0x1F00000). That memory belongs to the game:0x1FFC000–0x2000000, overlaps the default main-thread stack.SetupThreadwith stack-1puts that stack at the top of RAM.0x1FFC000and0x1FD9280–0x1FF5500. Those are exactly the addresses the first runtime stacks occupy. They only survive while callback stack use stays shallow.On real hardware, the EE kernel owns the first 1 MB of RAM and games load at
0x00100000or above. The runtime already uses0x0–0x80000for kernel-mirrored state (the syscall table mirror). That leaves0x00080000–0x00100000free.Change
[0x00080000, min(0x00100000, lowest PT_LOAD start)).loadELFworks out the ceiling from the lowest physical segment start, so KSEG0 ELFs work. The defaults (0x80000/0x100000) apply when no ELF is loaded.0x80000, or more than 32 stacks are needed), reservation falls back to the previous top-of-RAM carving. It logs one line per loaded ELF when that happens.invocationStackTop, the stack size, and the mutex.Testing
ps2_runtime_interrupt_tests.cpp, each written to fail first. They go through the realloadELFwith a small synthetic ELF.0x100000.[0x80000, 0x100000)without overlapping.0x000C0000keeps the stacks below it.ps2_gs_tests.cpp, "callback invocation should use the reserved async stack pool") expected stacks at or above0x01F00000. It now expects the kernel-area range.ps2x_tests: 450/450.0x0–0x80000mirror stayed byte-identical, and memory at0x100000was untouched.0x80000, mixed segment orders and back-to-back ELF loads all set the bounds correctly.Known limits, not changed here
EeScheduler::resetdoesn't clear its stack cache, whileloadELFresets the cursors. A second ELF load in one session could reuse cached stacks. This predates the change.Built and tested on macOS arm64 (Apple clang).