Difference between revisions of "IPC"
m |
|||
Line 51: | Line 51: | ||
close handle for caller | 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. | + | 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, and 2 are ignored. Types 5, 6, and 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. |
{| class="wikitable" border="1" | {| class="wikitable" border="1" |
Revision as of 21:16, 25 January 2016
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 second 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, and 2 are ignored. Types 5, 6, and 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.