The PS2 Direct Memory Access Controller
Introduction
The Direct Memory Access Controller (DMAC) is a vital component for maximising the performance of the PS2. In this article some of the basic features of the DMAC will be describes. This article is only meant to provide a flavour of the operation of the DMAC and those interested in further details are directed towards Chapter 5 of the EE User’s Manual.
The DMAC is responsible for intelligently transferring data between main memory and the peripheral processors and between main memory and scratchpad RAM. During DMAC transfers, the main CPU is freed from involvement, thus speeding up overall system operation. Data, which must be aligned on a qword (128 bit) boundary, is transferred in qword units. There are 10 DMAC channels that are allocated to various destinations within the PS2. Channels that are commonly used when creating applications under PS2 Linux are channel 0 to VIF0, channel 1 to/from VIF1, channel 2 to GIF and channels 8/9 from/to scratchpad RAM.
In
terms of performance, the DMAC can transfer data over the main bus at a maximum
rate of 2.4 Gbytes/sec. This can be compared with Intel’s Accelerated Graphics
Port (AGP) x4 bus that has a bus bandwidth of 1.1 Gbytes/sec and the AGPx8 bus
with a transfer rate of 2.1 Gbytes/sec.
Transfer
addresses given to the DMAC must be specified in terms of physical memory
addresses. Normal program variables and dynamically allocated memory in an
operating system such as Linux use virtual addresses which are constant for a
given program, but the physical address of these variables and memory can
change as the operating system pages them in, out and around physical memory.
This leads to one of the main purposes of the Direct PS2 Access Environment
(SPS2) module (which is required in order to directly access the DMAC under
PS2Linux), which is the allocation of un-swappable physical memory that is
guaranteed to have a constant physical address. In essence this feature of SPS2
allows the programmer to allocate un-swappable memory that can then be used by
the DMAC to transfer data to/from the various processors and scratchpad RAM.
There
are 4 different modes of DMAC transfer: Normal, source chain, destination
chain, and interleave. In this article only the normal and source chain
transfer modes will be discussed.
The
DMAC transfer process is controlled by a number of 32-bit registers within the
EE core. Some of these registers have multiple values packed together into bits
fields. The channel control register (CHCR), the memory address register
(MADR), and the quad word count register (QWC) are needed to set up a normal
mode DMAC transfer. The channel control register (CHCR), the tag address
register (TADR), and the quad word count register (QWC) are needed to set up a
chain mode DMAC transfer. SPS2 has predefined unions and structures which can
be used to configure these registers and there are pointers defined in order to
directly access these Emotion Engine registers.
Normal mode transfer moves a continuous section of data between main memory to one of the other processors or scratchpad RAM. All that is required to set up the transfer is to configure the three registers: QWC, MADR and CHCR. An instance of these registers exists for each of the DMAC channels and they are identified by prefixing the register name with the channel number, e.g. D0_CHCR refers to the channel control register for DMAC channel 0 to VIF0.
The
QWC register specified the number of qwords to be transferred and the MADR
register specifies the start address in memory of the data to be transferred.
The CHCR register has a number of fields but only two of them, the mode (MOD)
and the start (STR) are needed for normal mode transfers. The MOD field tells
the DMAC what mode of transfer is required, which in this case will be normal
mode. When the STR bit of the CHCR register is set to one the DMAC transfer is
started.
It
is possible to determine when the DMAC transfer has finished by sampling the
STR bit of the CHCR register; this bit is reset to zero when the transfer
completes.
An
example of using this DMAC in normal mode can be seen in the tutorial entitled
“Using The DMAC” which can be found at http://www.hsfortuna.pwp.blueyonder.co.uk/.
Source
chain mode allows data to be sent from multiple places in memory to one
destination using just one transfer initiation. This is achieved by feeding the
DMAC commands, called DMA tags. These DMA tags are used to find both the next
chunk of data to send and the next DMA tag if there is one.
DMA
tags are 128 bits long, but only the lower 64 bits are used. Anything can be
placed in the top 64 bits of the DMA tag and this is often taken advantage of
to insert VIF codes for example.
The
combination of the actual stream of data and DMA tags is called a DMA chain. A
DMA chain can be thought of as being made up of links, with each link having
one DMA tag and associated data.
The
QWC field of the DMA tag specifies how much data is in the link, measured in
quad words. Each tag can have a different type, which is set in the
identification (ID) field. The tag’s ID affects what value is put into the ADDR
field of the tag.
DMA
tags that are commonly used are cnt, next, ref, refe, and end. There are also
refs, call and ret tags but these are not described in this article. A short
explanation of each of these tags is given below.
cnt: This tag says to transfer QWC of data following
the tag, and then read the quad word after that data as the next DMA tag.
next: This tag says to transfer QWC of data following
the tag, and then read the next tag from the address in the ADDR field of the
tag.
ref: This tag says to transfer QWC of data from the
address in the ADDR field of the tag then read the quad word following this tag
as the next tag.
refe: This provides the same function as the ref tag
except that the transfer ends after transferring the data from the address in
the ADDR field.
end: This tag says to transfer QWC of data following
the tag, and then end the transfer.
These
tags can be seen in operation in the tutorial entitled “Using DMAC Tags” which
can be found at http://www.hsfortuna.pwp.blueyonder.co.uk/.
In
order to help understand the use of DMAC tags and source chain mode transfers
consider the table below which shows some data and DMA tags laid out in memory.
Note that the DMA tags and data are scattered around memory.
Address |
Contents |
0x0000 |
DMA Tag #1: ID = NEXT,
ADDR = 0x0030, QWC = 2 |
0x0010 |
String 1 |
0x0030 |
DMA Tag #2: ID = REF,
ADDR = 0x1000, QWC = 2 |
0x0040 |
DMA Tag #3: ID = CNT,
ADDR = 0, QWC = 2 |
0x0050 |
String 3 |
0x0070 |
DMA Tag #4: ID = END,
ADDR = 0, QWC = 2 |
0x0080 |
String 4 |
0x1000 |
String 2 |
The
DMAC is initiated and reads DMA Tag #1 from address 0x0000. It will transfer
the 2 quad words of string 1 and then read in DMA Tag #2 from the address
specified in the ADDR field of DMA tag #1. DMA Tag #2 causes the DMAC to
transfer the two quad words from the address in the ADDR field of DMA Tag #2,
which is String 2, and then read in DMA Tag #3. DMA Tag #3 tells the DMAC to
transfer the following two quad words, which is String 3, then read the quad
word after that as the next tag which is DMA Tag #4. The DMAC then transfers
the final two quad words (string 4) and ends the transfer. All the strings are
transferred in the order that is specified (strings 1 through to 4) even though
they are dotted around in memory.
This
short article has illustrated some of the features of the DMAC within the PS2.
It is worth mentioning that memory allocated under SPS2 is only physically
continuous in 4k blocks but the source chain mode feature of the DMAC can be
used to stitch these blocks together so that large chunks of data can be
transferred around the system under PS2 Linux.
Lecturer in Computer Games
Technology
University of Abertay
Dundee
Scotland UK
20 February 2004