GSP Shared Memory: Difference between revisions

Kynex7510 (talk | contribs)
Done edits
Kynex7510 (talk | contribs)
m Use conventional names
 
(3 intermediate revisions by the same user not shown)
Line 36: Line 36:
PDC interrupts are sent to all processes; other interrupts are only sent to the process with rendering rights.
PDC interrupts are sent to all processes; other interrupts are only sent to the process with rendering rights.


GSP will only dispatch PSC0 if a [[GSP_Shared_Memory#Trigger_Memory_Fill|Memory Fill]] command has been issued with both buffers set.
When issuing a [[GSP_Shared_Memory#Trigger_Memory_Fill|Memory Fill]] command with both buffers set GSP will only dispatch PSC0.


= Framebuffer Info =
= Framebuffer Info =
Line 98: Line 98:
See [[Configuration Memory]].
See [[Configuration Memory]].


= Command Queue =
= GX Command Queue =


The command queue is located at sharedMemBase + 0x800 + (clientID * 0x200). It consists of an header followed by at most 15 command entries. Each command entry is of size 0x20 and has an header followed by command specific parameters.
This command queue is located at sharedMemBase + 0x800 + (clientID * 0x200). It consists of an header followed by at most 15 command entries.


After adding a command, [[GSPGPU:TriggerCmdReqQueue|TriggerCmdReqQueue]] must be used to start command processing (official code does so when the total commands field is 1).
The queue header has the following structure:
 
== Command Queue Header ==


{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 118: Line 116:
|-
|-
| 2
| 2
| Status (bit0 = halted, bit7 = fatal error)
| Status (0x1 = halted, 0x80 = error)
|-
|-
| 3
| 3
Line 127: Line 125:
|}
|}


GSP checks for status.bit0 and optionally avoids handling further commands, however the check is done by equality, which means it will always fail if status.bit7 is also set (and thus other commands will be processed). This bug prevents the halting logic from working propertly, but can be worked around by keeping bit0 of word3 set, as that will force halting on each iteration.
After adding a command, [[GSPGPU:TriggerCmdReqQueue|TriggerCmdReqQueue]] must be used to start command processing (official code does so when the total commands field is 1).
 
== Commands ==
 
A command entry is made of 8 words. The first word is the command header, subsequent words represent command specific parameters.


== Command Header ==
The command header has the following structure:


{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 149: Line 151:
|}
|}


== Commands ==
Addresses specified in command parameters are virtual addresses. Depending on the command, there might be constraints on the accepted parameters. In general, some commands require parameters to be aligned, and addresses are expected to be on [[Memory_Management#Memory_Mapping|linear]], [[Memory_layout#0x1F000000_.28New_3DS_only.29|QTM]] or VRAM memory.


Addresses specified in parameters are virtual addresses. Depending on the command, there might be constraints on the accepted parameters. In general, some commands require parameters to be aligned, and addresses are expected to be on [[Memory_Management#Memory_Mapping|linear]], [[Memory_layout#0x1F000000_.28New_3DS_only.29|QTM]] or VRAM memory.
=== RequestDMA ===
 
=== Trigger DMA Request ===


{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 185: Line 185:
Any process must have acquired rendering rights, otherwise the command does nothing.
Any process must have acquired rendering rights, otherwise the command does nothing.


=== Trigger Command List Processing ===
=== ProcessCommandList ===


{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 217: Line 217:
Any process must have acquired rendering rights, otherwise the command does nothing.
Any process must have acquired rendering rights, otherwise the command does nothing.


=== Trigger Memory Fill ===
=== MemoryFill ===


{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 253: Line 253:
Addresses should be aligned to 8 bytes and must be in linear, QTM or VRAM memory, otherwise error 0xE0E02BF5 (GSP_INVALID_ADDRESS) is returned. The start address for a buffer must be below its end address, else the same error is returned. If the start address for a buffer is 0, that buffer is skipped; otherwise, its relative PSC unit is used for the fill operation.
Addresses should be aligned to 8 bytes and must be in linear, QTM or VRAM memory, otherwise error 0xE0E02BF5 (GSP_INVALID_ADDRESS) is returned. The start address for a buffer must be below its end address, else the same error is returned. If the start address for a buffer is 0, that buffer is skipped; otherwise, its relative PSC unit is used for the fill operation.


=== Trigger Display Transfer ===
=== DisplayTransfer ===


{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 286: Line 286:
No error checking is performed on the parameters. Addresses should be aligned to 8 bytes and should be in linear, QTM or VRAM memory, otherwise PA 0 is used.
No error checking is performed on the parameters. Addresses should be aligned to 8 bytes and should be in linear, QTM or VRAM memory, otherwise PA 0 is used.


=== Trigger Texture Copy ===
=== TextureCopy ===


{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 322: Line 322:
No error checking is performed on the parameters. Addresses and size should be aligned to 8 bytes, and the addresses should be in linear, QTM or VRAM memory, otherwise PA 0 is used.
No error checking is performed on the parameters. Addresses and size should be aligned to 8 bytes, and the addresses should be in linear, QTM or VRAM memory, otherwise PA 0 is used.


=== Flush Cache Regions ===
=== FlushCacheRegions ===


{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 359: Line 359:


Any process must have acquired rendering rights, otherwise the error 0xD8202A06 (GSP_NO_RIGHT) is returned.
Any process must have acquired rendering rights, otherwise the error 0xD8202A06 (GSP_NO_RIGHT) is returned.
== Bugs ==
* When issuing a DMA request, GSP attempts to acquire an internal semaphore that rules CDMA access; this semaphore is never released on failure paths. While this is generally not an issue, as GSP breaks on DMA failures, it becomes a problem if the DMA request is done with cache flushing: in that case, GSP will error silently, causing a deadlock in DMA code.
* When handling GX commands apart from RequestDMA and ProcessCommandList, GSP sets the relative busy flags in internal state before executing the commands. This means that, if the relevant interrupts are never triggered (eg. on invalid parameters), the busy flags never get reset, preventing execution of future commands of the same kind.