Memory map: Difference between revisions

Jump to navigation Jump to search
Content added Content deleted
Line 78: Line 78:
Cartridge Domains 1 and 2 are mapped one-to-one on the cartridge/bottom port. It is not known at this time what Domain 1 Address 3 was used for, if at all, but flash carts may have some use for that address range.
Cartridge Domains 1 and 2 are mapped one-to-one on the cartridge/bottom port. It is not known at this time what Domain 1 Address 3 was used for, if at all, but flash carts may have some use for that address range.


== Memory Map accesses ==
== Physical Memory Map accesses ==
The whole memory map is implemented by RCP, as the VR4300 only talks directly to RCP. The bus between VR4300 and RCP is called [[SysAD Interface|SysAD]]. The RCP behaves differently with different access sizes depending on the specific area of the map and the subcomponent in charge of implementing it.
The physical memory map is implemented by RCP, as the VR4300 only talks directly to RCP. The bus between VR4300 and RCP is called [[SysAD Interface|SysAD]]. The RCP behaves differently with different access sizes depending on the specific area of the map and the subcomponent in charge of implementing it.


The SysAD bus is described at the hardware level in the [[SysAD Interface|SysAD page]], but to understand the effects on memory map it is sufficient to understand how data is marshalled for reads and writes. Since SysAD is a 32-bit bus, 32-bit accesses are the "native" ones, and the others are made to work around a 32-bit data exchange.
The SysAD bus is described at the hardware level in the [[SysAD Interface|SysAD page]], but to understand the effects on memory map it is sufficient to understand how data is marshalled for reads and writes. Since SysAD is a 32-bit bus, 32-bit accesses are the "native" ones, and the others are made to work around a 32-bit data exchange.
Line 91: Line 91:
The accesses in this area are handled by RCP via RI (Ram Interface). When the VR4300 reads or writes a location in this range, it gets stalled while the RI communicates with the RDRAM via the RAMBUS serial protocol. As soon as the read or write is finished, the VR4300 is released. Effectively, all reads and writes are synchronous (blocking) from the point of view of the VR4300, as you would expect when accessing a RAM. All access sizes work correctly: 8-bit, 16-bit, 32-bit, 64-bit.
The accesses in this area are handled by RCP via RI (Ram Interface). When the VR4300 reads or writes a location in this range, it gets stalled while the RI communicates with the RDRAM via the RAMBUS serial protocol. As soon as the read or write is finished, the VR4300 is released. Effectively, all reads and writes are synchronous (blocking) from the point of view of the VR4300, as you would expect when accessing a RAM. All access sizes work correctly: 8-bit, 16-bit, 32-bit, 64-bit.


=== Range 0x03F0'0000 - 0x004F'FFFF (RCP registers) ===
=== Range 0x03F0'0000 - 0x04FF'FFFF (RCP registers) ===
The accesses in this area are handled by RCP itself without going to an external bus, and are dispatched internally to the correct subsystem. Access to a register might optionally stall the VR4300 if the subsystem is designed to do so (eg: to perform a long blocking operation on write), but in general for standard registers, they are immediate and take only 1 PClock cycle.
The accesses in this area are handled by RCP itself without going to an external bus, and are dispatched internally to the correct subsystem. Access to a register might optionally stall the VR4300 if the subsystem is designed to do so (eg: to perform a long blocking operation on write), but in general for standard registers, they are immediate and take only 1 PClock cycle.


Line 102: Line 102:
TODO
TODO


=== All other ranges 0x0500'0000 - 0xFFFF'FFFF (External SysAD bus via PI) ===
=== Other ranges 0x0500'0000 - 0x7FFF'FFFF (External bus via PI) ===
All accesses made by the VR4300 in these ranges are forward externally by RCP on the external bus via PI. This allows the CPU to access external devices like the cartridge ROM and SRAM.
All accesses made by the VR4300 in these ranges are forward externally by RCP on the external bus via PI. This allows the CPU to access external devices like the cartridge ROM and SRAM.


Line 111: Line 111:
* All writes are performed '''asynchronously''' by the PI. Making a write in this area will in fact just cause the PI to latch the value internally, and release the VR4300 immediately. The write will then happen in background. The status of the ongoing write will be reflected by the PI "I/O busy" status bit, which will be set to 1 until the write is finalized. While a write is ongoing, further writes are ignored, and reads (from any address) return the 32-bit value that is being written. For further information on this, please check the [[Peripheral Interface|PI page]].
* All writes are performed '''asynchronously''' by the PI. Making a write in this area will in fact just cause the PI to latch the value internally, and release the VR4300 immediately. The write will then happen in background. The status of the ongoing write will be reflected by the PI "I/O busy" status bit, which will be set to 1 until the write is finalized. While a write is ongoing, further writes are ignored, and reads (from any address) return the 32-bit value that is being written. For further information on this, please check the [[Peripheral Interface|PI page]].
* All external accesses are made by RCP through a 16-bit bus. Given that the RCP only knows of 32-bit accesses (as access size is ignored), this means that each read or write performed by the VR4300 will cause exactly two reads or two writes on the 16-bit bus: first the MSB at the address specified by the CPU (ignoring bit 0, so that the address is aligned to 16 bit), then the LSB at address+2. This might seem a small implementation detail, but it does actually cause an important and visible bug. For instance, if the VR4300 requests a 16-bit read at address <code>0x1000'0002</code>, the RCP (that ignores access sizes) will do two 16-bit reads on the cartridge bus at <code>0x1000'0002</code> and <code>0x1000'0004</code>, and will put on the SysAD bus the 32-bit word at <code>0x1000'0002 - 0x1000'0005</code>. This is a violation of the SysAD protocol explained above: in fact, in reply to a 16-bit read at <code>0x1000'0002</code>, the RCP should have put on the bus the 32-bit word at <code>0x1000'0000 - 0x1000'0003</code> instead. Because of this, effectively a 16-bit read at <code>0x1000'0002</code> returns the 16-bit word at <code>0x1000'0004</code> instead.
* All external accesses are made by RCP through a 16-bit bus. Given that the RCP only knows of 32-bit accesses (as access size is ignored), this means that each read or write performed by the VR4300 will cause exactly two reads or two writes on the 16-bit bus: first the MSB at the address specified by the CPU (ignoring bit 0, so that the address is aligned to 16 bit), then the LSB at address+2. This might seem a small implementation detail, but it does actually cause an important and visible bug. For instance, if the VR4300 requests a 16-bit read at address <code>0x1000'0002</code>, the RCP (that ignores access sizes) will do two 16-bit reads on the cartridge bus at <code>0x1000'0002</code> and <code>0x1000'0004</code>, and will put on the SysAD bus the 32-bit word at <code>0x1000'0002 - 0x1000'0005</code>. This is a violation of the SysAD protocol explained above: in fact, in reply to a 16-bit read at <code>0x1000'0002</code>, the RCP should have put on the bus the 32-bit word at <code>0x1000'0000 - 0x1000'0003</code> instead. Because of this, effectively a 16-bit read at <code>0x1000'0002</code> returns the 16-bit word at <code>0x1000'0004</code> instead.

=== Range 0x8000'0000 - 0xFFFF'FFFF (Unmapped) ===
This range is not handled by RCP. All writes are ignored, and reads lock up the VR4300 because the RCP does not return any data on the bus.