RSPCOP0

From en64 wiki
Jump to navigation Jump to search

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 Figure.png
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