Changes

35 bytes added ,  18:08, 26 March 2019
no edit summary
Line 31: Line 31:  
| ... || || [[#Buffer descriptor A/B/W "Send"/"Receive"/"Exchange"|Buf B descriptors]], each one 3 words.
 
| ... || || [[#Buffer descriptor A/B/W "Send"/"Receive"/"Exchange"|Buf B descriptors]], each one 3 words.
 
|-
 
|-
| ... || || [[#Buffer descriptor A/B/W "Send"/"Receive"/"Exchange"|Type W descriptors]], each one 3 words.
+
| ... || || [[#Buffer descriptor A/B/W "Send"/"Receive"/"Exchange"|Buf W descriptors]], each one 3 words.
 
|-
 
|-
 
| ... || || [[#Raw_data_section|Raw data section]] (including padding before and after aligned data section).
 
| ... || || [[#Raw_data_section|Raw data section]] (including padding before and after aligned data section).
Line 172: Line 172:  
Used to enforce whether or not device mapping is allowed for src and dst buffers respectively.
 
Used to enforce whether or not device mapping is allowed for src and dst buffers respectively.
 
   
 
   
* Flag0: Device mapping *not* allowed for src or dst.
+
* Ipc (flag=0): Device mapping *not* allowed for src or dst.
* Flag1: Device mapping allowed for src and dst.
+
* NonSecureIpc (flag=1): Device mapping allowed for src and dst.
* Flag3: Device mapping allowed for src but not for dst.
+
* NonDeviceIpc (flag=3): Device mapping allowed for src but not for dst.
    
=== Buffer descriptor C "ReceiveList" ===
 
=== Buffer descriptor C "ReceiveList" ===
Line 289: Line 289:     
== Official marshalling code ==
 
== Official marshalling code ==
The official marshalling function takes an array of (buf_ptr, size) pairs and a type-field for each such pair.
+
The official marshalling function is called "nn::sf::hipc::client::Hipc2ClientCoreProcessorImpl::WriteBufferDataImpl" and takes:
 
+
* A pointer to a "nn::sf::hipc::detail::HipcMessageWriter" context;
Bitmask 0x10 seems to indicate null-terminated strings.
+
* The number of (buf_ptr, size) pairs;
 +
* An array of (buf_ptr, size) pairs (called "nn::sf::detail::PointerAndSize");
 +
* A pointer to a type bitfield for each such pair;
 +
* The offset of the main IPC command structure;
 +
* The size of the IPC command's [[IPC_Marshalling#Raw_data_section|raw data]].
    +
The type of an IPC command is described by a bitfield as below:
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
! Type Mask || Description || Direction
+
! Bits || Description
|-
  −
| 4 + 1 || Creates a A descriptor with flags=0. || In
  −
|-
  −
| 0x40 + 4 + 1 || Creates a A descriptor with flags=1. || In
  −
|-
  −
| 0x80 + 4 + 1 || Creates a A descriptor with flags=3. || In
   
|-
 
|-
| 4 + 2 || Creates a B descriptor with flags=0. || Out
+
| 0 || Direction is input.
 
|-
 
|-
| 0x40 + 4 + 2 || Creates a B descriptor with flags=1. || Out
+
| 1 || Direction is output.
 
|-
 
|-
| 0x80 + 4 + 2 || Creates a B descriptor with flags=3. || Out
+
| 2 || Use buffer descriptors A ("Send"), B ("Receive") or W ("Exchange").
 
|-
 
|-
| 8 + 1 || Creates an X descriptor || In
+
| 3 || Use buffer descriptors X ("Pointer") or C ("ReceiveList").
 
|-
 
|-
| 8 + 2 || Creates a C descriptor, and writes the u16 size to an offset into raw data. || Out
+
| 4 || Skip saving the pointer buffer size in raw data.
 
|-
 
|-
| 0x10 + 8 + 2 || Creates a C descriptor || Out
+
| 5 || Select which buffer descriptor to use automatically.
 
|-
 
|-
| 0x20 + 1 || Creates both an A and X descriptor || In
+
| 6 || Use [[Flags|NonSecureIpc flag]].
 
|-
 
|-
| 0x20 + 2 || Creates both an B and C descriptor || Out
+
| 7 || Use [[Flags|NonDeviceIpc flag]].
|-
  −
| 0x20 + 2 + 0x40 || Same as 0x20 + 2, except a certain value is set to hard-coded 0x1 instead. || Out
   
|}
 
|}
    
C and X (Pointer and ReceiveList) descriptors are backed by the "pointer buffer", a buffer in the service process. Its size is a u16, which is retrieved using the "QueryPointerBufferSize" control message. If the client code determines all buffers with flag 8 do not fit in the pointer buffer, it returns error 0x11A0B.
 
C and X (Pointer and ReceiveList) descriptors are backed by the "pointer buffer", a buffer in the service process. Its size is a u16, which is retrieved using the "QueryPointerBufferSize" control message. If the client code determines all buffers with flag 8 do not fit in the pointer buffer, it returns error 0x11A0B.
   −
For buffers with flag 0x20 it creates two descriptors (A+X or B+C), but one descriptor is NULL (zero size and pointer), while the other holds the expected values. X/C descriptors are used as the non-NULL descriptor where possible, but if they don't fit in the pointer buffer, A/B descriptors are used instead. The code defers processing of type 0x20 buffers with sizes that fit in a u16 (and may therefore fit in the pointer buffer). This ensures all type 8 buffers get pointer-buffer space before any type 0x20.
+
For buffers with flag 0x20 it creates two descriptors (A+X or B+C), but one descriptor is NULL (zero size and pointer), while the other holds the expected values. X/C descriptors are used as the non-NULL descriptor where possible, but if they don't fit in the pointer buffer, A/B descriptors are used instead. The code defers processing of type 0x20 buffers with sizes that fit in a u16 (and may therefore fit in the pointer buffer), which ensures all type 8 buffers get pointer-buffer space before any type 0x20. The order in which the deferred type 0x20 buffers are processed is determined by a convoluted loop.
 
  −
(The order in which the deferred type 0x20 buffers are processed is determined by a convoluted loop.)
      
== Official IPC Cmd Structure ==
 
== Official IPC Cmd Structure ==