Skip to content
Wolfvak edited this page Apr 19, 2018 · 1 revision

GodMode9 mainly runs on the ARM9 CPU (ARM946E-S) on the 3DS, but as there are certain hardware registers that can simply not be accessed from it, GM9 needs to be able to talk to the ARM11 CPU (MPCore11).

This is achieved using built-in hardware (PXI) that's available on the console, with both CPUs using a very simple protocol to send messages to each other.

Currently implemented commands are available here.

Protocol overview

Both CPUs must have been synchronized to have their PXISync Remote port set to PXI_READY at some point earlier. The receiving CPU must also have interrupts enabled and properly set up, or periodically poll the PXISync Remote port register.

Whenever CPU A wants to send a command to CPU B:

1) CPU A makes sure CPU B is ready to accept a command (Remote port is `PXI_READY`).
2) CPU A sends up to 16 32-bit parameters. The parameter count depends on the command.
3) CPU A sets its Remote port to the command ID.
4) CPU A triggers a PXISync interrupt which will be picked up by CPU B.
5) CPU A waits on a tight loop until CPU B's Remote port is `PXI_BUSY`.

At Step 4, CPU B will receive a processor hardware interrupt and execute the PXI command handler. This handler will:

1) Read the Remote port of CPU A to get the command ID.
2) Depending on the command, it'll receive up to 16 32-bit parameters onto a local buffer.
3.0) If the command is asynchronous, the Remote port will be set to `PXI_BUSY`.
3.1) Execute the desired command with the specified arguments.
3.2) If the command is synchronous, the Remote port will be set to `PXI_BUSY`.
4) The Remote port will be set to `PXI_READY`.

Adding new commands

Due to GM9 limitations, interrupts must be masked on the ARM9 at all times. Therefore, it is not possible to send commands from the ARM11 to the ARM9.

In order to add a new command, a new ID must be added to common/pxi.h and the code to handle it has to be implemented in mpcore/source/main.c. There's a "template" present, plus two currently implemented commands that can be used as examples.

Clone this wiki locally