IPC Command Structure

This is an array of u32's.

Word Bits Description
0 15-0 IPC version? Always 4.
0 19-16 Number of buf X descriptors (each: 2 words).
0 23-20 Number of buf A descriptors (each: 3 words).
0 27-24 Number of buf B descriptors (each: 3 words).
0 31-28 Number of type W desciptors (each: 3 words), never observed.
1 9-0 Size of data portion in u32's.
1 13-10 If set to 2, enable buf C descriptor.
1 31 Enable handle descriptor.
... Handle descriptor, if enabled.
... Buf X descriptors, each one 2 words.
... Buf A descriptors, each one 3 words.
... Buf B descriptors, each one 3 words.
... Type W descriptors, each one 3 words.
... Padding
... Raw data
... Buf C descriptors, each one 2 words.

Handle descriptor

There can only be one of this descriptor type. It is enabled by bit31 of the second word.

Word Bits Description
0 0 Send current PID or process handle (?).
0 4-1 Number of handles.
0 8-5 Number of B-words for this special descriptor.
... Two words are reserved here if bit0 is set.
... Handles
... B-words, purpose unknown.

Buffer descriptor A/B

This packing is so unnecessarily complex.

Word Bits Description
0 Lower 32-bits of size.
1 Lower 32-bits of address.
2 1-0 Always set to 1 or 3. R/RW.
2 4-2 Bit 38-36 of address.
2 27-24 Bit 35-32 of size.
2 31-28 Bit 35-32 of address.

Buffer descriptor C

Word Bits Description
0 Lower 32-bits of address.
1 15-0 Rest of address.
1 31-16 Size

Buffer descriptor X

This one is packed even worse than A, they inserted the bit38-36 of the address on top of the counter field.

Word Bits Description
0 5-0 Bits 5-0 of counter.
0 8-6 Bit 38-36 of address.
0 11-9 Bits 11-9 of counter.
0 15-12 Bit 35-32 of address.
0 31-16 Size
1 Lower 32-bits of address.

Raw data portion

This is an array of u64's. It's always aligned to 16 so sometimes there is padding words before it.

Word Description
0 Magic ("SFCI" for requests, "SFCO" for responses)
1 Cmd id
... Non-marshalled data is placed here

Official marshalling code

The official marshalling function takes an array of (buf_ptr, size) pairs and a type-field for each such pair.

Bitmask 0x10 seems to indicate null-terminated strings, but that flag is ignored by the marshalling code.

Type Mask Description
4 + 1 Creates an A descriptor
4 + 2 Creates a B descriptor
8 + 1 Creates an X descriptor
8 + 2 Creates a C descriptor
0x20 + 1 Creates both an A and X descriptor