MIPS Interface: Difference between revisions

Document what MI_MODE actually does.
No edit summary
(Document what MI_MODE actually does.)
Line 17:
==== <span style="display:none;">0x0430 0000 - MI_MODE</code> ====
----
 
'''When Reading:'''
 
{{#invoke:Register table|head|550px|MI_MODE <code>0x0430 0000</code>}}
{{#invoke:Register table|row|31:24}}
| U-0 || U-0 || U-0 || U-0 || U-0 || U-0 || U-0 || U-0
|-
| — || — || — || — || — || — || — || —
{{#invoke:Register table|row|23:16}}
| U-0 || U-0 || U-0 || U-0 || U-0 || U-0 || U-0 || U-0
|-
| — || — || — || — || — || — || — || —
{{#invoke:Register table|row|15:8}}
| U-0 || U-0 || W-0 || W-0 || W-0 || W-0 || R-0 || R-0
|-
| — || — || — || — || — || — || Upper || Ebus
{{#invoke:Register table|row|7:0}}
| R-0 || RW-0 || RW-0 || RW-0 || RW-0 || RW-0 || RW-0 || RW-0
|-
| — || —Repeat || colspan="67" | Details BelowRepeatCount[6:0]
{{#invoke:Register table|foot}}
{{#invoke:Register table|definitions
| 9 | Upper | Upper mode enabled.
| 8 | EBus | EBus mode enabled.
| 7 | Repeat | Repeat mode enabled, Automatically clears after a single write.
| 6-0 | RepeatCount[6:0] | Number of bytes (minus 1) to write in repeat mode
}}
 
'''When Writing:'''
 
{{#invoke:Register table|head|550px|MI_MODE <code>0x0430 0000</code>}}
{{#invoke:Register table|row|31:24}}
Line 29 ⟶ 59:
| U-0 || U-0 || W-0 || W-0 || W-0 || W-0 || RW-0 || RW-0
|-
| — || — || Set Upper || Clear Upper || ClearDP || Clear Ebus || Set Ebus || Clear Repeat
| — || — || colspan="6" | Details Below
{{#invoke:Register table|row|7:0}}
| RWW-0 || RW-0 || RW-0 || RW-0 || RW-0 || U-0 || RW-0 || RW-0
|-
| DetailsSet BelowRepeat || colspan="7" | INIT_LENGTHRepeatCount[6:0]
{{#invoke:Register table|foot}}
{{#invoke:Register table|definitions
<pre>
| 13 | SetUpper | Set Ebus mode.
READ: WRITE:
| 12 | ClearUpper | Set Ebus mode.
[13] — [13] Set RDRAM register mode
| 11 | ClearDP | Clear the DP interrupt
[12] — [12] Clear RDRAM register mode
| 10 | ClearEBus | Clear Ebus mode.
[11] — [11] Clear DP interrupt
| 9 | SetEBus | Set Ebus mode.
[10] — [10] Set ebus test mode
| 8 | ClearRepeat | Clear repeat mode.
[9] RDRAM register mode [9] Clear ebus test mode
| 7 | SetRepeat | Set repeat mode. Automatically clears after a single write.
[8] ebus test mode [8] Set init mode
| 6-0 | RepeatCount[76:0] | Number of initbytes mode [7](minus 1) to write Clearin initrepeat mode
}}
[6:0] init length [6:0] init length
 
</pre>'''Extra Details:'''
'''MI's Modes:'''
: '''RDRAM Register mode:''' this mode must be set while reading RDRAM registers to obtain the correct data for odd registers. What it actually does, at the physical level, is that it "mangles" all memory accesses in the RDRAM physical address space (so, including accesses to actual RAM contents) so that the upper half of each 64-bit word is returned also for 32-bit accesses to the lower half. This is necessary because RDRAM registers have 32-bit alignment in the memory map, but the data coming from the RDRAM bus is always 64-bit.
 
The mode controls how 32bit SysAD bus transfers are mapped onto DBus and EBus.
 
RI only uses 64bit aligned reads/writes when accessing RDRAM. For operations smaller than 64bits, the data needs to be shifted into the correct bytes of DBUS. When writing, the Rambus device will use the lower 3 bits of the address and byte count as a byte mask. When reading, all 64bits are returned and the receiving device will need to implement its own byte masking.
 
The VR4300's pipeline already shifts smaller memory operations into the correct part of the 64bit double word and implements byte masking for reads, but because 8bit/16bit/32bit operations only result in 32bits of data being transferred across SysAD bus, MI needs to shift each 32bit word into the correct half of DBus.
 
These modes impact all reads and writes to the RDRAM address range, both regular memory and registers. Reads and Writes to other RCP registers and MMIO (like SI, PI or RSP DMEM/IMEM) are unaffected, as that data goes over CBus.
 
: '''Normal mode:''' MI word maps onto the DBus as expected. 32bit words are shifted into the upper or low half of the 64bits depending on Addr[2] and any critical word first rules. EBus appears to default to the sign extension of each byte (further testing needed)
 
: '''Upper mode:''' 32bit transfers are always shifted into the upper half of the 64bit bus.<Br>
This mode is labeled as '''"RDRAM register mode"''' in some documentation and is useful for accessing registers on Rambus devices. The Rambus Rreg, Wreg, and WregB commands are hardcoded to ignore the count field of request packets and always do a 32bit transfers. When misinterpreting the RI's 8 byte transfer, the Rambus device always takes the first 4 bytes (which are the upper 32bits of DBus, because RCP is big endian) and ignores the next 4 bytes. Normal mode should produce correct results for registers at even offsets, but you need switch MI into Upper mode to correctly access odd registers.
 
: '''EBus modę:''' The lower 4 bits of the 32bit word are mapped onto 4 bits of EBus.<Br>
In typical operation, EBus is used by RDP and VI to access the extra 9th bit (aka parity/error bit) that RDRAM provides for each byte. This mode allows the CPU to read this extra information back.<Br> Unfortunately this doesn't appear to be useful for writing to AA framebuffers, as there isn't a way to combine a normal mode write and a EBus mode write without overwriting each other.
 
: '''Repeat Mode:''' 32bit writes result in <code>RepeatCount + 1</code> bytes being written, with the same 32bit word repeating every 32bits. Reading with this mode causes a hang. <br>In this mode, MI duplicates the 32bit word into both the upper and lower half of DBUS, and then lies to RI about the transfer count. Instead of 4, it sends ```RepeatCount```. The full Count is inserted into the Rambus request packet and the Rambus device uses the lower 3 bits for byte masking. RI looks at RepeatCount[6:3] to calculate the number 64bit transfers.
 
: This mode is labeled as '''"Init Mode"''' in some documentation. It's only used once during IPL3's RDRAM initialization to do a broadcast write to the '''Delay''' register. This is needed because after reset, the default timings in the '''Delay''' register result in the Rambus device sampling the data from the Rambus way too late and sampling garbage data. RI's timings are baked into hardware and can't be changed, but IPL3 uses a clever trick:<Br>
By enabling Repeat Mode and setting RepeatCount to 15, the 32bit value is repeated 4 times, and the Rambus device now samples the data we need to write into the '''Delay''' register. However, the default timings aren't off by an integer multiple of the RCP clock, so the Rambus device actually halfway between two repetitions of the 32bit word. So IPL3 takes the additional step of rotating the value by 16 bits before writing.
 
 
==== <span style="display:none;">0x0430 0004 - MI_VERSION</code> ====
----
22

edits