JIT services: Difference between revisions
No edit summary |
|||
(5 intermediate revisions by the same user not shown) | |||
Line 49: | Line 49: | ||
== GenerateCode == | == GenerateCode == | ||
Takes an u32, an u64, a [[#CodeRange]], a [[#CodeRange]], a [[#Struct32]], a type-0x5 input buffer, a type-0x6 output buffer, and returns an output s32, a [[#CodeRange]], a [[#CodeRange]]. | Takes an u32, an u64, a [[#CodeRange]], a [[#CodeRange]], a [[#Struct32]], a type-0x5 input buffer, a type-0x6 output buffer, and returns an output s32, a [[#CodeRange]], a [[#CodeRange]]. | ||
sdknso copies data from an user-buffer to the tmp [[#Struct32]] which is used with the cmd, the size of that user-buffer is passed as the cmd input u32. | |||
An error is thrown if the funcptr in state for the "nnjitpluginGenerateCode" symbol is not set. | An error is thrown if the funcptr in state for the "nnjitpluginGenerateCode" symbol is not set. | ||
Line 54: | Line 56: | ||
This does a bunch of validation. Then eventually CodeMemory/TransferMemory is mapped, the above symbol funcptr is called, runs more validation, and unmaps CodeMemory/TransferMemory. On success, this runs cache operations. Then this returns. | This does a bunch of validation. Then eventually CodeMemory/TransferMemory is mapped, the above symbol funcptr is called, runs more validation, and unmaps CodeMemory/TransferMemory. On success, this runs cache operations. Then this returns. | ||
The funcptr is called with the following params: x0 = s32* out, x1 = {ptr to output [[#CodeRange]] initialized with the input [[#CodeRange]] and with the second u64 cleared}, x2 = {ptr to output [[#CodeRange]] initialized with the input [[#CodeRange]] and with the second u64 cleared}, x3 = {ptr to struct on stack which is the same as the one used for the "nnjitpluginOnPrepared" symbol, except +0x30/+0x38 is set | The funcptr is called with the following params: x0 = s32* out, x1 = {ptr to output [[#CodeRange]] initialized with the input [[#CodeRange]] and with the second u64 cleared}, x2 = {ptr to output [[#CodeRange]] initialized with the input [[#CodeRange]] and with the second u64 cleared}, x3 = {ptr to struct on stack which is the same as the one used for the "nnjitpluginOnPrepared" symbol, except +0x30/+0x38 are set to the sysmodule map-addr for each CodeMemory (addr for the second CodeMemory is set properly)}, x4 = cmd input u64, x5 = InBuffer addr, x6 = InBuffer size, x7 = {ptr to input [[#CodeRange]]}, sp0 = {ptr to input [[#CodeRange]]}, sp8 = {ptr to input [[#Struct32]]}, sp16 = cmd input u32, sp24 = OutBuffer addr, sp32 = OutBuffer size. | ||
The input/output [[#CodeRange]] structs are validated as follows, where stateval is the first/second CodeMemory [[#CreateJitEnvironment|size]] for the first/second [[#CodeRange]]: | The input/output [[#CodeRange]] structs are validated as follows, where stateval is the first/second CodeMemory [[#CreateJitEnvironment|size]] for the first/second [[#CodeRange]]: | ||
Line 67: | Line 69: | ||
* in_CodeRange.size must be >= out_CodeRange.size. | * in_CodeRange.size must be >= out_CodeRange.size. | ||
* (out_CodeRange.offset-in_CodeRange.offset) must be <= (in_CodeRange.size-out_CodeRange.size). | * (out_CodeRange.offset-in_CodeRange.offset) must be <= (in_CodeRange.size-out_CodeRange.size). | ||
After using the cmd, sdknso runs cache operations. | |||
== Control == | == Control == | ||
Line 91: | Line 95: | ||
* TransferMemory init is done here. An ASLR'd address for the TransferMemory mapped-address is determined, which will then be reused for all later mappings. | * TransferMemory init is done here. An ASLR'd address for the TransferMemory mapped-address is determined, which will then be reused for all later mappings. | ||
* CodeMemory init func-calling is done for both regions, where w1={first output from "nnjitpluginConfigure" above}. Likewise with the TransferMemory, with w1={second output from "nnjitpluginConfigure" above}. | * CodeMemory init func-calling is done for both regions, where w1={first output from "nnjitpluginConfigure" above}. Likewise with the TransferMemory, with w1={second output from "nnjitpluginConfigure" above}. | ||
* "nnjitpluginOnPrepared", error is handled on failure. Before/after calling this symbol funcptr, the TransferMemory is mapped/unmapped. The symbol funcptr is called with x0 = {ptr to struct on stack}. The struct has following structure: +0 = 0x20-bytes of data from state, +0x20 = TransferMemory map-addr, +0x28 = TransferMemory size, and +0x30 size 0x10-bytes is cleared. | * "nnjitpluginOnPrepared", error is handled on failure. Before/after calling this symbol funcptr, the TransferMemory is mapped/unmapped. The symbol funcptr is called with x0 = {ptr to struct on stack}. The struct has following structure: +0 = 0x20-bytes of data from state {user-process map-addr/size for each CodeMemory, used by [[#GetCodeAddress]]}, +0x20 = TransferMemory map-addr, +0x28 = TransferMemory size, and +0x30 size 0x10-bytes is cleared. | ||
* Then this does cleanup and returns. | * Then this does cleanup and returns. | ||
Line 115: | Line 119: | ||
== Struct32 == | == Struct32 == | ||
This is "nn::jitsrv::Struct32". This is a 0x20-byte struct. This is 8-byte aligned. | This is "nn::jitsrv::Struct32". This is a 0x20-byte struct. This is 8-byte aligned. | ||
This contains arbitrary plugin-specific input data which is passed to the [[#GenerateCode]] funcptr. | |||
= Title usage = | |||
There are no system-titles using jit:u. The only titles using it are the following: | |||
* [[Super Mario 3D All-Stars]] (N64 emulation only) | |||
* [[Nintendo 64 - Nintendo Switch Online]] |