RDRAM Interface: Difference between revisions
(Add RI_REFRESH description) |
(Add reference to N64 patent) |
||
Line 4: | Line 4: | ||
The base address for these registers is <code>0x0470 0000</code>, also known as RI_BASE. However, because all memory accesses in the CPU are made using virtual addresses, the following addresses must be offset appropriately. For non-cached reads/writes, add <code>0xA000 0000</code> to the address. As an example, to directly write to the RI_MODE register, use address <code>0xA470 0000</code>. |
The base address for these registers is <code>0x0470 0000</code>, also known as RI_BASE. However, because all memory accesses in the CPU are made using virtual addresses, the following addresses must be offset appropriately. For non-cached reads/writes, add <code>0xA000 0000</code> to the address. As an example, to directly write to the RI_MODE register, use address <code>0xA470 0000</code>. |
||
Some information is available in [https://patentimages.storage.googleapis.com/cc/33/96/6e54e1628ec0f9/US6593929.pdf US6593929.pdf] in paragraph "Example Memory Controller/Interface Registers" and associated figures (37A-H). |
|||
= Registers = |
= Registers = |
Revision as of 22:33, 14 December 2022
The RDRAM Interface (or RI) is one of multiple I/O interfaces in the RCP. It acts as a controller for the RDRAM channel to which one or more RDRAM modules are connected. It converts memory accesses from the system into RDRAM protocol commands for the RDRAM bus. The RI integrates a RDRAM ASIC Cell (or RAC) in order to take care of the low level details of the RDRAM bus. Further details about such a RAC can be found in datasheets for similar RACs (however not necessarily the same version used by the N64).
There are two sets of memory mapped registers for RDRAM configuration. One set is specifically for writing to or reading from the configuration registers in one or all individual RDRAM module(s). The other set, defined in the next section, configure this RDRAM interface. Refer to Memory map for the full map, including all RDRAM-related segments.
The base address for these registers is 0x0470 0000
, also known as RI_BASE. However, because all memory accesses in the CPU are made using virtual addresses, the following addresses must be offset appropriately. For non-cached reads/writes, add 0xA000 0000
to the address. As an example, to directly write to the RI_MODE register, use address 0xA470 0000
.
Some information is available in US6593929.pdf in paragraph "Example Memory Controller/Interface Registers" and associated figures (37A-H).
Registers
Table Notation:
R = Readable bit W = Writable bit U = Undefined/Unused bit -n = Default value n at boot -? = Unknown default value [x:y] = Specifies bits x to y, inclusively
RI_MODE 0x0470 0000
| ||||||||
---|---|---|---|---|---|---|---|---|
31:24 | U-0 | U-0 | U-0 | U-0 | U-0 | U-0 | U-0 | U-0 |
— | — | — | — | — | — | — | — | |
23:16 | U-0 | U-0 | U-0 | U-0 | U-0 | U-0 | U-0 | U-0 |
— | — | — | — | — | — | — | — | |
15:8 | U-0 | U-0 | U-0 | U-0 | U-0 | U-0 | U-0 | U-0 |
— | — | — | — | — | — | — | — | |
7:0 | U-0 | U-0 | U-0 | U-0 | RW-1 | RW-1 | RW-? | RW-? |
— | — | — | — | STOP_R | STOP_T | OP_MODE[1:0] |
bit 31-4 | Undefined: Initialized to 0
|
bit 3 | STOP_R: Automatic halting of RAC clock used for receive logic when not in use, normally enabled. 1 = Enabled 0 = Disabled |
bit 2 | STOP_T: Automatic halting of RAC clock used for transmit logic when not in use, normally enabled. 1 = Enabled 0 = Disabled |
bit 1-0 | OP_MODE[1:0]: Controls how Serial Mode (SMode) packets are sent to RDRAM modules. [1] Usually set to 10 . 11 = Unknown 10 = Sends a packet before each RDRAM transaction. Tells the modules to enter standby mode after receiving each transaction. 01 = Sends a packet every 4 BusClk cycles. Tells the modules to always be active (consumes more power and usually not used). 00 = Sends continuous packets. After 272 BusClk cycles, all RDRAM modules will enter a reset mode. Due to the timing differences, some changes will require a delay to become active. |
RI_CONFIG 0x0470 0004
| ||||||||
---|---|---|---|---|---|---|---|---|
31:24 | U-? | U-? | U-? | U-? | U-? | U-? | U-? | U-? |
— | — | — | — | — | — | — | — | |
23:16 | U-? | U-? | U-? | U-? | U-? | U-? | U-? | U-? |
— | — | — | — | — | — | — | — | |
15:8 | U-? | U-? | U-? | U-? | U-? | U-? | U-? | U-? |
— | — | — | — | — | — | — | — | |
7:0 | U-? | RW-? | RW-? | RW-? | RW-? | RW-? | RW-? | RW-? |
— | AutoCC | CC [5:0] |
READ?/WRITE: [6] Enable/Disable automatic current calibration from controller. It selects whether the the value CC[5:0] will be written to current control register (AutoCC=0), or an internally generated value (AutoCC=1). [5:0] Current Control Input. The value to be loaded into current control register when autoCC is disabled.
RI_CURRENT_LOAD 0x0470 0008
| ||||||||
---|---|---|---|---|---|---|---|---|
31:24 | U-? | U-? | U-? | U-? | U-? | U-? | U-? | U-? |
— | — | — | — | — | — | — | — | |
23:16 | U-? | U-? | U-? | U-? | U-? | U-? | U-? | U-? |
— | — | — | — | — | — | — | — | |
15:8 | U-? | U-? | U-? | U-? | U-? | U-? | U-? | U-? |
— | — | — | — | — | — | — | — | |
7:0 | U-? | U-? | U-? | U-? | U-? | U-? | U-? | U-? |
— | — | — | — | — | — | — | — |
WRITE: TOVERIFY: Any write to this register will load a new value into the current control register. The value loaded depends on the value of AutoCC. See RI_CONFIG for details. TOVERIFY: When AutoCC=1, a sufficient delay should be observed to let CC autocalibration stabilize.
RI_SELECT 0x0470 000C
| ||||||||
---|---|---|---|---|---|---|---|---|
31:24 | U-? | U-? | U-? | U-? | U-? | U-? | U-? | U-? |
— | — | — | — | — | — | — | — | |
23:16 | U-? | U-? | U-? | U-? | U-? | U-? | U-? | U-? |
— | — | — | — | — | — | — | — | |
15:8 | U-? | U-? | U-? | U-? | U-? | U-? | U-? | U-? |
— | — | — | — | — | — | — | — | |
7:0 | RW-? | RW-? | RW-? | RW-? | RW-? | RW-? | RW-? | RW-? |
TSEL [3:0] | RSEL [3:0] |
bit 31-8 | Undefined: Undefined |
bit 7-4 | TSEL[3:0]: Configure transmit signals timings. Very likely related to RAC signals B{C,D,E}Sel. Usually set to 0x1 .
|
bit 3-0 | RSEL[3:0]: Configure receive signals timings. Very likely related to RAC signal RDSel. Usually set to 0x4 .
|
RI_REFRESH 0x0470 0010
| ||||||||
---|---|---|---|---|---|---|---|---|
31:24 | U-? | U-? | U-? | U-? | U-? | U-? | U-? | U-? |
— | — | — | — | — | — | — | — | |
23:16 | U-? | U-? | U-? | RW-? | RW-? | RW-? | RW-? | RW-? |
— | — | — | MultiBank[??:0] | Opt | En | Bank | ||
15:8 | RW-? | RW-? | RW-? | RW-? | RW-? | RW-? | RW-? | RW-? |
DirtyRefreshDelay [7:0] | ||||||||
7:0 | RW-? | RW-? | RW-? | RW-? | RW-? | RW-? | RW-? | RW-? |
CleanRefreshDelay [7:0] |
bit 31-?? | Undefined: Undefined |
bit ??-19 | MultiBank[??:0]: Bitfield indicating multibanks rdram modules. (Bitfield size to be determined, very likely between 2 and 8). Probably why RDRAM modules are re-ordered with multibanks modules first. |
bit 18 | Opt: Optimize. Usually set to 0x1 .
|
bit 17 | En: Enable. Usually set to 0x1 .
|
bit 16 | Bank: Usually set to 0x0 .
|
bit 15-8 | DirtyRefreshDelay[7:0]: Usually set to 0x36 .
|
bit 7-0 | CleanRefreshDelay[7:0]: Usually set to 0x34 .
|
TODO: remaining registers
Memory addressing
RI translate memory accesses in the range 0x0000 0000
- 0x03FF FFFF
into suitable RDRAM protocol packets with proper command type and 36 bit address. See RDRAM addressing paragraph for details about how 36bit addresses are interpreted.
Address conversion done by RI (TOVERIFY):
Address Range | Adr[35:29] | Adr[28:20] | Adr[19:11] | Adr[10:0] | BCastRWrite | Description | |
---|---|---|---|---|---|---|---|
0x0000 0000
|
0x03EF FFFF
|
0 | (address >> 20) & 0x3F | (address >> 11) & 0x1FF | address & 0x7FF | 0 | Memory-space access |
0x03F0 0000
|
0x03F7 FFFF
|
0 | (address >> 10) & 0x1FF | (address >> 10) & 0x1FF | address & 0x3FF | (address >> 19) & 0x1 == 0 | Register-space access |
0x03F8 0000
|
0x03FF FFFF
|
0 | (address >> 10) & 0x1FF | (address >> 10) & 0x1FF | address & 0x3FF | (address >> 19) & 0x1 == 1 | Broadcast register write |
Examples :
Assuming a standard RDRAM configuration of 4x2x9Mbit RDRAM each with IdField = 2*k for module k = 0..3 and SwapField = 0 for all modules (eg. no address swapping, Adr = AdrS).
- Reading at address 0x003A BCDE, gives the following Adr[35:20] = 3, Adr[19:0] = 0xABCDE, BCastRWrite = 0. Since we have 2x9Mbit modules, Adr[20] is ignored for Id matching and therefore RDRAM with IdField == 2 gives a match. This means RDRAM module 1 will be read at address 0x1ABCDE.
- Writing at address 0x03F0 0808, gives Adr[35:20] = 2, Adr[19:0] = 8, BCastRWrite = 0. Which means writing to RDRAM module 1 delay register.
- Writing at address 0x03F8 0008, gives BCastRWrite = 1, Adr[19:0] = 8. Which means broadcast writing to all RDRAM modules delay registers.
Remarks :
- Early version of RCP reserved fewer bits for RDRAM register address (eg. Adr[35:20] = (address >> 9) & 0x3FF; Adr[19:0] = address & 0x1FF) which didn't allow to access RDRAM register 128 (Row register) which is at offset 0x200.
- The presented address map supports up to 32x 2x9Mbit RDRAM modules.
- Standard DRAM initialization only supports up to 8 modules, but can mix 2x9Mbit and 1x9Mbit modules. In that case, 2x9Mbit modules are placed before 1x9Mbit modules.
- Standard DRAM initialization procedure, doesn't make use of address swapping feature, even though it may increase DRAM hit rate according to datasheets.
- Register-space addresses duplicates the content between Adr[28:20] and Adr[19:11] to not be affected by RDRAM address swapping features. Indeed, whereas address swapping is desirable for RDRAM memory to benefit from row internal row caching, registers won't benefit from the swapping and would complicate usage of registers in such a case.