RSPCOP0
The RSP Coprocessor 0 (RSPCOP0) is used to control the DMA engine, RSP status, RDP status, and RDP I/O (which is how the CPU controls the RCP). Essentially it serves the purpose of handling communication between the processors. The following registers are programmed using the mtc0 and mtf0 instructions. The RSP Coprocessor 0 registers (and certain other RSP registers) are memory-mapped into the host CPU address space.
Number | Name rsp.h |
Mode | Description |
---|---|---|---|
$c0 | DMA_CACHE (0x04040000) |
RW | I/DMEM address for DMA |
$c1 | DMA_DRAM (0x04040004) |
RW | DRAM address for DMA |
$c2 | DMA_READ_LENGTH (0x0404008) |
RW | DMA READ length (DRAM -> i/DMEM) |
$c3 | DMA_WRITE_LENGTH (0x0404000c) |
RW | DMA WRITE length (DRAM <- I/DMEM) |
$c4 | SP_STATUS (0x04040010) |
RW | RSP Status |
$c5 | DMA_FULL (0x04040014) |
R | DMA full |
$c6 | DMA_BUSY (0x04040018) |
R | DMA busy |
$c7 | SP_RESERVED (0x0404001c) |
RW | CPU-RSP Semaphore |
$c8 | CMD_START (0x04100000) |
RW | RDP command buffer START |
$c9 | CMD_END (0x04100004) |
RW | RDP command buffer END |
$c10 | CMD_CURRENT (0x04100008) |
R | RDP command buffer CURRENT |
$c11 | CMD_STATUS (0x0410000c) |
RW | RDP Status |
$c12 | CMD_CLOCK (0x04100010) |
RW | RDP clock counter |
$c13 | CMD_BUSY (0x04100014) |
R | RDP command buffer BUSY |
$c14 | CMD_PIPE_BUSY (0x04100018) |
R | RDP pipe BUSY |
$c15 | CMD_TMEM_BUSY (0x0410001c) |
R | RDP TMEM BUSY |
"Other RSP Addresses"
Address | Mode | Description |
---|---|---|
0x04000000 | RW | RSP DMEM (4096 bytes) |
0x04001000 | RW | RSP IMEM (4096 bytes) |
0x04080000 | RW | RSP Program Counter (PC), 12 bits |
Registers Detailed
$c0
This register hold the RSP IMEM or DMEM address for a DMA transfer. (a=0: DMEM, a=1: IMEM)
__1_________12________ | | IMEM or DMEM | | a | Address | |_____|________________| 12 11 0 On power-up, this register is 0x0.
$c1
This register holds the DRAM address for a DMA transfer. This is a physical memory address.
__________24__________ | | | DRAM address | |______________________| 23 0 On power-up, this register is 0x0.
$c2, $c3
These registers hold the DMA transfer length; $c2 is used for a READ, $c3 is used for a WRITE.
___12________8_________12____ | | | | | skip | count | length | |________|_________|__________| 31 20 19 12 11 0 On power-up, these registers are 0x0. The three fields of this register are used to encode arbitrary transfers of rectangular areas of DRAM to/from contiguous I/DMEM. length is the number of bytes per line to transfer, count is the number of lines, and skip is the line stride, or skip value between lines. This is illustrated in the Figure below:
DMA Transfer Length Encoding
Note: DMA length and line count are encoded as (value -1), that is a line count of 0 means 1 line, a byte length of 7 means 8 bytes, etc. A straightforward linear transfer will have a count of 0 and skip of 0, transferring (length+1) bytes. The amount of data transferred must be a multiple of 8 bytes (64 bits), hence the lower three bits of length are ignored and assumed to be all 1's. DMA transfer begins when the length of register is written. For more information about DMA transfers, see section "DMA" below.
$c4
This register holds the RSP status.
__1____1____1____1____1____1____1____1____1____1____1____1____1___1___1_ | | | | | | | | | | | | | | | | | s7 | s6 | s5 | s4 | s3 | s2 | s1 | s0 | ib | ss | if | df | db | b | h | |____|____|____|____|____|____|____|____|____|____|____|____|____|___|___| 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Bit | Field | Mode | Description |
---|---|---|---|
0 | h | RW | RSP is halted |
1 | b | R | RSP has encountered a break instruction |
2 | db | R | DMA is busy |
3 | df | R | DMA is full |
4 | if | R | IO is full |
5 | ss | RW | RSP is in single-step mode |
6 | ib | RW | Interrupt on break |
7 | s0 | RW | signal 0 is set |
8 | s1 | RW | signal 1 is set |
9 | s2 | RW | signal 2 is set |
10 | s3 | RW | signal 3 is set |
11 | s4 | RW | signal 4 is set |
12 | s5 | RW | signal 5 is set |
13 | s6 | RW | signal 6 is set |
14 | s7 | RW | signal 7 is set |
The 'broke', 'single-step', and 'interrupt on break' bits are used by the debugger. The signal bits can be used for user-defined synchronization between the CPU and RSP. On power-up, this register contains 0x0001.
When writing the RSP status register, the following bits are used.
Bit | Description |
---|---|
0 (0x00000001) |
clear HALT |
1 (0x00000002) |
set HALT |
2 (0x00000004) |
clear BROKE |
3 (0x00000008) |
clear RSP interrupt |
4 (0x00000010) |
set RSP interrupt |
5 (0x00000020) |
clear SINGLE STEP |
6 (0x00000040) |
set SINGLE STEP |
7 (0x00000080) |
clear INTERRUPT ON BREAK |
8 (0x00000100) |
set INTERRUPT ON BREAK |
9 (0x00000200) |
clear SIGNAL 0 |
10 (0x00000400) |
set SIGNAL 0 |
11 (0x00000800) |
clear SIGNAL 1 |
12 (0x00001000) |
set SIGNAL 1 |
13 (0x00002000) |
clear SIGNAL 2 |
14 (0x00004000) |
set SIGNAL 2 |
15 (0x00008000) |
clear SIGNAL 3 |
16 (0x00010000) |
set SIGNAL 3 |
17 (0x00020000) |
clear SIGNAL 4 |
18 (0x00040000) |
set SIGNAL 4 |
19 (0x00080000) |
clear SIGNAL 5 |
20 (0x00100000) |
set SIGNAL 5 |
21 (0x00200000) |
clear SIGNAL 6 |
22 (0x00400000) |
set SIGNAL 6 |
23 (0x00800000) |
clear SIGNAL 7 |
24 (0x01000000) |
set SIGNAL 7 |
$c5
This register maps to bit 3 of the RSP status register, DMA_FULL. It is read only.
On power-up, this register is 0x0.
$c6
This register maps to bit 2 of the RSP status register, DMA_BUSY. It is read only.
On power-up, this register is 0x0.
$c7
This register is a hardware semaphore for synchronization with the CPU, typically used to share the DMA activity. If this register is 0, the semaphore may be acquired. This register is set on read, so the test and set is atomic. Writing 0 to this register releases the semaphore.
GetSema: MFC0 $1, $c7 BNE $1, $0, GetSema NOP # do critical work ReleaseSema: MTC0 $0, $7
On power-up, this register is 0x0.
$c8
This register holds the RDP command buffer START address. Depending on the state of the RDP STATUS register, this address is interpreted by the RDP as either a 24 bit physical DRAM address, or a 12 bit DMEM address (see $c11).
__________24___________ | | | RDP Command Start | |_______________________| 23 0
On power-up, this register is undefined.
$c9
This register holds the RDP command buffer END address. Depending on the state of the RDP STATUS register, this address is interpreted by the RDP as either a 24 bit physical DRAM address, or a 12 bit DMEM address (see $c11).
__________24___________ | | | RDP Command End | |_______________________| 23 0
On power-up, this register is undefined.
$c10
This register holds the RDP command buffer CURRENT address. This register is READ ONLY. Depending on the state of the RDP STATUS register, this address is interpreted by the RDP as either a 24 bit physical DRAM address, or a 12 bit DMEM address (see $c11).
__________24___________ | | | RDP Command Current | |_______________________| 23 0
On power-up, this register is 0x0.
$c11
This register holds the RDP status.
10_9__8__7__6__5__4__3_2__1_0 | | | | | | | | | | | | |sv|ev|db|cr|cb|pb|tb|g|fl|f|x| |__|__|__|__|__|__|__|_|__|_|_| 1 1 1 1 1 1 1 1 1 1 1
RDP Status Register
Bit | Field | Mode | Description |
---|---|---|---|
0 | x | RW | Use XBUS DMEM DMA or DRAM DMA |
1 | f | RW | RDP is frozen |
2 | fl | RW | RDP is flushed |
3 | g | RW | GCLK is alive |
4 | tb | R | TMEM is busy |
5 | pb | R | RDP PIPELINE is busy |
6 | cb | R | RDP COMMAND unit is busy |
7 | cr | R | RDP COMMAND buffer is ready |
8 | db | R | RDP DMA is busy |
9 | ev | R | RDP COMMAND END register is valid |
10 | sv | R | RDP COMMAND START register is valid |
When bit 0 (XBUS_DMEM_DMA) is set, the RDP command buffer is receive data from DMEM (see $c8, $c9, $c10).
On power-up, the GCLK, PIPE_BUSY, and CMD_BUF_READY bits are set, the DMA_BUSY bit is undefined, and all other bits are 0.
When writing the RDP status register, the following bits are used:
Bit | Description |
---|---|
0 (0x0001) |
clear XBUS DMEM DMA |
1 (0x0002) |
set XBUS DMEM DMA |
2 (0x0004) |
clear FREEZE |
3 (0x0008) |
set FREEZE |
4 (0x0010) |
clear FLUSH |
5 (0x0020) |
set FLUSH |
6 (0x0040) |
clear TMEM COUNTER |
7 (0x0080) |
set PIPE COUNTER |
8 (0x0100) |
clear COMMAND COUNTER |
9 (0x0200) |
clear CLOCK COUNTER |
$c12
This register holds a clock counter, incremented on each cycle of the RDP clock. This register is READ ONLY.
__________24___________ | | | RDP Clock Counter | |_______________________| 23 0
On power-up, this register is undefined.
$c13
This register holds a RDP command buffer busy counter, incremented on each cycle of the RDP clock while the RDP command buffer is busy. This register is READ ONLY.
__________24____________ | | |RDP Command Busy Counter| |________________________| 23 0
On power-up, this register is undefined.
$c14
This register holds a RDP pipe busy counter, incremented on each cycle of the RDP clock that the RDP pipeline is busy. This register is READ ONLY.
__________24___________ | | | RDP Pipe Busy Counter | |_______________________| 23 0
On power-up, this register is undefined.
$c15
This register holds a RDP TMEM load counter, incremented on each cycle of the RDP clock while the TMEM is loading. This register is READ ONLY.
__________24___________ | | | RDP TMEM Load Counter | |_______________________| 23 0
On power-up, this register is undefined.
CPU Point of View
DMA
All data operated on by the RSP must first be DMA'd into DMEM. RSP programs can also use DMA to load microcode into IMEM. Note: Loading microcode on top of the currently executing code at the PC will result in undefined behavior.
Alignment Restrictions
All data sources and destinations for DMA transfers must be aligned to 8 bytes (64 bits), in both DRAM and I/DMEM. Transfer length must be multiples of 8 bytes (64 bits).
Timing
Peak transfer rate is 8 bytes (64 bits) per cycle. There is a DMA setup overhead of 6-12 clocks, so longer transfers are more efficient. IMEM and DMEM are single-ported memories, so accesses during DMA transfers will impact performance.
DMA Full
The DMA registers are double-buffered, having one pending request one current active request. The DMA FULL condition means that there is an active request and a pending request, so no more requests can be serviced.
DMA Wait
Waiting for DMA completion is under complete programmer control. When DMA_BUSY is cleared, the transition is complete. If there is a pending DMA transaction, this transaction will be serviced before DMA_BUSY is cleared.
DMA Address Bits
Since all DMA accesses must be 64-bit aligned, the lower three bits of source and destination address are ignored and assumed to be all 0's. Transfer lengths are encoded as (length -1), so the lower three bits of the length are ignored and assumed to be all 1's. The DMA LENGTH registers can be programmed with a line count and line stride, to transfer arbitrary rectangular pieces of memory (such as a portion of an image). See "DMA Transfer Length Encoding" above/from earlier for more information.
CPU Semaphore
The CPU-RSP semaphore should be used to share DMA resources. Since the CPU could possibly DMA data to/from the RSP while the RSP is running, this semaphore is necessary to share the DMA engine. Note: The current graphics and audio microcode assume the CPU will not be DMA'ing data to/from the RSP while the RSP is running. This eliminates the need to check the semaphore (on the RSP side), saving a few instructions.
Examples to be here tomorrow!
Controlling the RDP
The RDP has an independent DMA engine which reads commands from DMEM or DRAM into the command buffer. The RDP command buffer registers are programmed to direct the RDP from where to read the command data.
How to Control the RDP Command FIFO
RDP commands are transferred from memory to the command buffer by the RDP's DMA engine. The RDP command buffer logic examines the CMD_CURRENT and CMD_END registers and will transfer data, 8 bytes (64 bits) at a time, advancing CMD_CURRENT, until CMD_CURRENT = CMD_END. CMD_START and CMD_END registers are double buffered, so they can be updated asynchronously by the RSP or CPU while the RDP is transferring data. Writing to these registers will set the START_VALID and/or END_VALID bits in the RDP status register, signaling the RDP to use the new pointers once the current transfer is complete. When a new CMD_START pointer is used, CMD_CURRENT is reset to CMD_START.
Algorithm to program the RDP Command FIFO:
- start with CMD_START and CMD_END set to the same initial value
- write RDP commands to memory, beginning at CMD_START
- when an integral number of RDP commands have been stored to memory, advance CMD_END (CMD_END should point to the next byte after the RDP command)
- keep advancing CMD_END as subsequent RDP commands are stored to memory
EXAMPLES HERE TOMORROW TOO