Hardware/Latte IPC
Latte IPC | |
Latte Registers | |
Access | |
---|---|
Espresso | Partial |
Starbuck | Full |
Registers | |
Base | 0x0d800000, 0x0d800400 |
Length | 0x10, 0x30 |
Access size | 32 bits |
Byte order | Big Endian |
IRQs | |
Espresso | 9, 10, 11 |
Latte | 30, 31 |
The Latte's IPC engine is generally used as a signalling system for communications between the PPC and ARM. The hardware consists of two general-purpose registers, and two flag pairs. Each side can set either of two flags, and the other side can read them or clear them and configure them to generate a Latte interrupt. The hardware is symmetric.
Operation
Conceptually, the IPC system can be seen as four bit flags which may be set or cleared: X1, X2, Y1, and Y2. These same four flags are visible in both control registers in different places. X1 and X2 can be read/set/cleared by the Espresso, but can only be read/cleared by the Starbuck. The Starbuck can configure individually whether X1 or X2 generate an interrupt (#31). The opposite is true for Y1 and Y2: they can be read/set/cleared by the Starbuck, but only read/cleared by the Espresso. The Espresso can configure whether these generate an interrupt (#30).
Note that, since the interrupts can actually route to either or both the Starbuck and Espresso, and since the Starbuck can also access the Espresso's registers, there are ways of abusing these flags for odd purposes.
Registers HW_IPCIOPCTRL and LT_IPCIOPCTRLx can only be accessed by the Starbuck. The others can be accessed by both CPUs.
Register List
The Latte IPC engine has two different register blocks: a global block compatible with the old Wii hardware (Wood), and a new SMP block split across the three Wii U's (Latte) PPC cores. Each core's region of the SMP block has registers equivalent to the old global block.
Wood block
Wood block | |||
---|---|---|---|
Address | Bits | Name | Description |
0x0d800000 | 32 | HW_IPCPPCMSG | Espresso data register for vWii |
0x0d800004 | 32 | HW_IPCPPCCTRL | Espresso flags and control for vWii |
0x0d800008 | 32 | HW_IPCIOPMSG | Starbuck data register for vWii |
0x0d80000c | 32 | HW_IPCIOPCTRL | Starbuck flags and control for vWii |
Latte block
Latte block - PPC core 0 | |||
---|---|---|---|
Address | Bits | Name | Description |
0x0d800400 | 32 | LT_IPCPPCMSG0 | Espresso data register for PPC core 0 |
0x0d800404 | 32 | LT_IPCPPCCTRL0 | Espresso flags and control for PPC core 0 |
0x0d800408 | 32 | LT_IPCIOPMSG0 | Starbuck data register for PPC core 0 |
0x0d80040c | 32 | LT_IPCIOPCTRL0 | Starbuck flags and control for PPC core 0 |
Latte block - PPC core 1 | |||
---|---|---|---|
Address | Bits | Name | Description |
0x0d800410 | 32 | LT_IPCPPCMSG1 | Espresso data register for PPC core 1 |
0x0d800414 | 32 | LT_IPCPPCCTRL1 | Espresso flags and control for PPC core 1 |
0x0d800418 | 32 | LT_IPCIOPMSG1 | Starbuck data register for PPC core 1 |
0x0d80041c | 32 | LT_IPCIOPCTRL1 | Starbuck flags and control for PPC core 1 |
Latte block - PPC core 2 | |||
---|---|---|---|
Address | Bits | Name | Description |
0x0d800420 | 32 | LT_IPCPPCMSG2 | Espresso data register for PPC core 2 |
0x0d800424 | 32 | LT_IPCPPCCTRL2 | Espresso flags and control for PPC core 2 |
0x0d800428 | 32 | LT_IPCIOPMSG2 | Starbuck data register for PPC core 2 |
0x0d80042c | 32 | LT_IPCIOPCTRL2 | Starbuck flags and control for PPC core 2 |
Register Details
LT_IPCPPCMSGx (0x0d800400/0x0d800410/0x0d800420) | |
310 | |
Access | R/W |
This is a general purpose 32-bit register that can be freely read/written by both CPUs. It is usually set by the Espresso and read by the Starbuck, though this is not a requirement. In IOSU, this register contains a pointer to a 0x48-byte structure in memory.
LT_IPCPPCCTRLx (0x0d800404/0x0d800414/0x0d800424) | ||||||||||||||||
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | |
Access | U | |||||||||||||||
Field | ||||||||||||||||
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
Access | U | R/W | R/W | R/W | R/Z | R/Z | R/W | |||||||||
Field | IY2 | IY1 | X2 | Y1 | Y2 | X1 |
Field | Description |
X1 | Read/write flag X1 |
Y2 | Read flag Y2. To clear the flag, write 1 to this bit. |
Y1 | Read flag Y1. To clear the flag, write 1 to this bit. |
X2 | Read/write flag X2 |
IY1 | If set, flag Y1 generates Latte interrupt #30 |
IY2 | If set, flag Y2 generates Latte interrupt #30 |
This register exposes the Espresso side of the IPC control. Flags X1 and X2 may be freely set/cleared. Flags Y1 and Y2 can be read and cleared (by writing one), and can optionally generate IRQ #30.
IOS usage
Field | Description |
X1 | Execute command: a new pointer is available in LT_IPCPPCCTRLx |
Y2 | Command acknowledge |
Y1 | Command executed and reply available in LT_IPCIOPMSGx |
X2 | Relaunch |
LT_IPCIOPMSGx (0x0d800408/0x0d800418/0x0d800428) | |
310 | |
Access | R/W |
This is a general purpose 32-bit register that can be freely read/written by both CPUs. It is usually set by the Starbuck and read by the Espresso, though this is not a requirement.
LT_IPCIOPCTRLx (0x0d80040c/0x0d80041c/0x0d80042c) | ||||||||||||||||
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | |
Access | U | |||||||||||||||
Field | ||||||||||||||||
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
Access | U | R/W | R/W | R/W | R/Z | R/Z | R/W | |||||||||
Field | IX2 | IX1 | Y2 | X1 | X2 | Y1 |
Field | Description |
Y1 | Read/write flag Y1 |
X2 | Read flag X2. To clear the flag, write 1 to this bit. |
X1 | Read flag X1. To clear the flag, write 1 to this bit. |
Y2 | Read/write flag Y2 |
IX1 | If set, flag X1 generates Latte interrupt #31 |
IX2 | If set, flag X2 generates Latte interrupt #31 |
This register exposes the Starbuck side of the IPC control. Flags Y1 and Y2 may be freely set/cleared. Flags X1 and X2 can be read and cleared (by writing one), and can optionally generate IRQ #31. The Espresso does not have any kind of access to this register.