Difference between revisions of "IPC"

From 3dbrew
Jump to navigation Jump to search
(This page needs some love from people who know how it actually works :()
m
Line 1: Line 1:
 
IPC commands are written to the [[Thread Local Storage]] at offset 0x80 and submitted using [[SVC|svcSendSyncRequest]]. If the kernel was able to dispatch the request, the server reply will be written to TLS+0x80. Often the first word of the response data is the error code (or 0 if success).
 
IPC commands are written to the [[Thread Local Storage]] at offset 0x80 and submitted using [[SVC|svcSendSyncRequest]]. If the kernel was able to dispatch the request, the server reply will be written to TLS+0x80. Often the first word of the response data is the error code (or 0 if success).
  
Every IPC command sent to services starts with a u32 header code, and parameters, if any, are written after this header. The can be decomposed in the following parts:
+
Every IPC command sent to services starts with a u32 header code, and parameters, if any, are written after this header. They are decomposed into the following parts:
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-

Revision as of 16:28, 3 December 2015

IPC commands are written to the Thread Local Storage at offset 0x80 and submitted using svcSendSyncRequest. If the kernel was able to dispatch the request, the server reply will be written to TLS+0x80. Often the first word of the response data is the error code (or 0 if success).

Every IPC command sent to services starts with a u32 header code, and parameters, if any, are written after this header. They are decomposed into the following parts:

Bits Description
0-5 Number of translate parameters (=y)
6-11 Number of normal parameters (=x)
12-15 Unused
16-31 Command ID

The entire command has the following structure:

Word Size Description
0 1 Header code
1 x Normal parameters
x y Translate parameters

Translate parameters are modified/translated transparently by the kernel. They are used to transfer handles/buffers between the different processes.

The type of parameter is described by the bits 1-3 in the translation descriptor. Parameter types accepted for sending by the kernel are: 0, 1, 2, 5, 6, 7. Type 0 is used to send handles across processes:

if desc & 0x30 == 0x20:
  write process id to value
else:
  translate handle
  if desc & 0x30 == 0x10:
    close handle for caller

For replies, only 0, 1, 5, 6, 7 are allowed. In other words any type 2 fields must be zeroed before calling svcReplyAndReceive on the server-side. For replies type 0, 1, 2 are ignored. Types 5, 6, 7 do something with the mem pointer upon reply. The type 0 descriptor can be used to ignore parameters. The number of parameters covered by a type-0 descriptor is (desc >> 26) + 1.

Type Usual form Description
0 0x00000000 | ((num_handles-1)<<26)

<handle 0>

<handle 1> ...

The corresponding values are KHandles, that should be closed in calling process. Or zero otherwise.
0 0x00000010 | ((num_handles-1)<<26)

<handle 0>

<handle 1> ...

The corresponding values are KHandles, that will be duplicated. Or zero otherwise.
0 0x00000020

<placeholder>

Let kernel set value to calling process ProcessID.
1 0x00000002 | (size<<14) | (static_buffer_id<<10)

<ptr>

The corresponding value contains a ptr to a buffer of said size, that should be copied to an already set-up buffer in destination process at Thread Local Storage offset 0x180 + static_buffer_id*8. The static_buffer_id is only 4 bits, making it possible for at most up to 16 buffers in total per thread.
2 0x00000004 | (size<<8) | (id<<4)

<ptr>

This is used for RW buffers over PXI. The address written to the destination cmd-buf is a phys-addr for a table located in the BASE memregion. This table contains the phys-addrs for the actual data, the array entries have the following format: {u32 *datachunk_physaddr, u32 datachunk_bytesize}.
3 0x00000006 | (size<<8) | (id<<4)

<ptr>

Same as above except for read-only buffer.
4 0x00000008 This command will cause a kernelpanic.
5 0x0000000A | (size<<4)

<ptr>

The corresponding value contains a ptr to a buffer of said size. It is mapped R- in the destination process??
6 0x0000000C | (size<<4)

<ptr>

The corresponding value contains a ptr to a buffer of said size. It is mapped -W in the destination process??
7 0x0000000E | (size<<4)

<ptr>

The corresponding value contains a ptr to a buffer of said size. It is mapped RW in the destination process??

Buffers from commands 5,6,7 will get mapped at virtual address 0x04000000+ in destination process.