aboutsummaryrefslogtreecommitdiff
path: root/NX2_NOTES.md
diff options
context:
space:
mode:
authorTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-27 14:58:15 -0400
committerTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-27 14:58:15 -0400
commit3063037b9945c3d5d3b9b34d02764c93103ebb27 (patch)
tree334e38d66270184dea02e751d11171ba7dc31cc0 /NX2_NOTES.md
parent58e1e35e1026d1a3eac87a82a22ac28bdbea8dc3 (diff)
NX2_NOTES: graphics boot through vi2 and NVN device init
Diffstat (limited to 'NX2_NOTES.md')
-rw-r--r--NX2_NOTES.md36
1 files changed, 27 insertions, 9 deletions
diff --git a/NX2_NOTES.md b/NX2_NOTES.md
index 28ee42d839..5ebfbe9161 100644
--- a/NX2_NOTES.md
+++ b/NX2_NOTES.md
@@ -74,6 +74,13 @@ With the patched decoder, games 1/3/4 only leave ~60-110 rare SIMD encodings in
| 16 | (title 4) `nn::gs::sdk::BootGraphicsSystem` -> `nn::os::GetRemoteMemoryUsage` abort | `svcGetInfo` 31/32 (remote memory for gsv/nvsrv) | return 0 for both (logged) |
| 17 | (title 4) `nn::gsv::BootWithRemoteMemory` abort | it sends TIPC on a session handle from `ISelfController` 2000, which had no handler | `ISelfController` 2000 returns a raw session to `INx2GraphicsSystemSession` (`nx2_gsv.h`), which accepts every command |
| 18 | (title 3) `nn::oe::GetPseudoDeviceId` abort | needs control.nacp, which loose ExeFS lacks | seed from program id |
+| 19 | (title 4) `nn::syncpt::sdk::InitializeEx` | gsv 202 must return the syncpt session; gsv 204 takes two transfer memories and must leave a header (version 1, count, offsets) in the read-only one and return two events; syncpt 1 returns a u32 < 0x400 | `INx2SyncptSession`, gsv 202/204 |
+| 20 | (title 4) `nn::gpu::sdk::BootWithRemoteMemory` | gsv 497 returns the GPU session; gpu 11 (id range), 12(id) event, 21(id) start + wait on that event, 22 another session | `INx2GpuSession` |
+| 21 | (title 4) `nn::vi2::sdk::Initialize` / `nn::vi::CreateLayer` | gsv 305 returns the vi2 session; vi2 1/3/5 return small u32s (5 = timestamp recorder count, 7 needed by LayerHistory), 11/31/32 return handles | `INx2Vi2Session` |
+| 22 | all TIPC replies with data | Eden bug: `ResponseBuilder::Push(Result)` writes the 2-word CMIF result, so TIPC data lands one word late and past the copied size | `TipcReplyWords` |
+| 23 | (title 4) NVN -> NvRm device open | nvsrv is the nvdrv INvDrvServices protocol; serve it with Eden's nvdrv, initialised without `Initialize` | nvdrv-backed `nx2:nvsrv` |
+| 24 | NvRm chip check | Switch 2 NvRm asks for a 0xD0-byte characteristics block and accepts chips 0x17E/0x12B/0x12E, but NVN needs the Ampere one; s16 interface versions at 0x70..0x80 must be >= 6 etc. | report chip 0x17E, Ampere classes, versions 0x40; unknown ctrl-gpu ioctls zero-stubbed for such callers |
+| 25 | NvRm address space | AllocAsEx(flags 5, no big pages, [0x8000000, 0xC000000000), split 0); NVN then reserves 4 KiB VA up to 512 GiB; Eden's split/limit handling made the reported regions unusable | small pages up to the end, absolute big-page limit |
Also changed: `svcGetInfo` 29/30 now report the upper half of the alias region instead of an
empty region (guess: VAMM address space). It made no visible difference for title 1.
@@ -88,17 +95,25 @@ All runs: `EDEN_NX2_AUTO_STUB=1`, 12 GB memory layout, loose ExeFS with the sibl
**Title 4** (`fourth switch game\exefs`, 0400380020056000) gets furthest. Path:
rtld -> nn::init -> nnosInitialize -> VAMM -> nn::oe (applet proxy, window, focus, graphics
-scale) -> fsp-srv + RomFS reads -> `nnMain` -> `nn::gs::sdk::BootGraphicsSystem`:
-- `nn::os::GetRemoteMemoryUsage` (svcGetInfo 31/32) -> stubbed 0/0.
-- `nn::gsv::BootWithRemoteMemory`: gets a session from `ISelfController` 2000 and sends TIPC
- 4 (region, process handle, pid), 11, 101, 1501, 1502. Placeholder `nx2:gsv` accepts all.
-- `nn::nvsrv::BootWithRemoteMemory`: `gsv` 1402 returns the nvsrv session (handle at word 3,
- result at word 4); nvsrv command 13 follows. Placeholder `nx2:nvsrv` accepts all.
-- `nn::syncpt::sdk::InitializeEx`: `gsv` 201, then 202 returns the syncpt session (same reply
- layout). Placeholder `nx2:syncpt`. See the end of this section for the latest stop.
+scale) -> fsp-srv + RomFS reads -> `nnMain` -> `nn::gs::sdk::BootGraphicsSystem` (gsv, nvsrv,
+syncpt, gpu sessions all booted) -> `nn::vi::Initialize` (vi2, default display opened) ->
+`nn::vi::CreateLayer` (layer + 7 timestamp recorders) -> RomFS asset loading, hid (touch 1920x1080,
+npad), acc, aoc -> NVN device init:
+- NvRm opens `/dev/nvhost-ctrl-gpu`, GetCharacteristics3 (Ampere 0x17E), GetTPCMasks3, 0x4713,
+ 0x471F, QueryEvent; gpu 41 ("NvRmGpu"), 33, 203, 202; opens `/dev/nvhost-as-gpu`, AllocAsEx,
+ GetVARegions (count, then data). `NvRmGpuDeviceOpen` and `NvRmGpuAddressSpaceCreate` succeed;
+ the 4 KiB VA reservation validates.
+- **Stops:** NVN's GPU init (`sdk+0x667a40`, called from `sdk+0x65cbd8`) still takes its failure
+ path afterwards, tears the device down (two nvdrv Close calls), and NVN later calls
+ `NvRmGpuDeviceZbcAddColor` through a null device (`sdk+0x667ccc`, PC=0). The exact failing step
+ after the address space is not pinned yet (no AllocSpace ioctl is issued).
+- Debugging this needs `EDEN_NX2_AUTO_STUB=1`, `tools/nx2/gdbrsp.py` against Eden's gdbstub
+ (`use_gdbstub=true`, fixed `rng_seed`, sdk at 0x84F30000), and `nso_syms.py` to resolve PLT
+ imports (vtable targets via breakpoints).
**Title 3** (`third switch game\exefs`, 04005B902517C000): same path, plus `GetPseudoDeviceId`
-(fixed), and reaches `nn::nvsrv::BootWithRemoteMemory` like title 4.
+(fixed); last checked at `nn::nvsrv::BootWithRemoteMemory`, before the later gsv/gpu/vi2 work, so
+it should now get about as far as title 4.
**Title 1** (`first switch game\exefs`, 0400C3F00006E000, `Drive.nss`): stops earlier, inside
`nnMain` (`nnMain+0x40 .. +0xb74`): it builds an SDK allocator object at address 0 (writes to
@@ -123,6 +138,9 @@ That's the bulk of a Switch 2 emulator and well beyond boot fixes.
## Prioritized next steps
+0. **Finish NVN device init** on title 4 (see the stop above), then GPU channel creation
+ (`/dev/nvhost-gpu`, GPFIFO submission) and the vi2 present path. The first realistic
+ milestone is a cleared frame: clears need no shaders.
1. **Keep walking title 4's graphics boot** with the IPC trace: each `nx2:` stub call in the log
is a command whose reply layout is needed. Use `nso_syms.py` + `nso_dis.py` on the SDK caller
to read the expected reply words (as done for 1402/202).