PS2 Linux Programming

 

Using DMAC Tags

 

 

Introduction

 

This tutorial will provide further information on the use of the Direct Memory Access Controller (DMAC) within the PS2. As mentioned in the tutorial “Using The DMAC”, SPS2 introduces an added complication in that the memory it allocates is only physically contiguous in 4k chunks. This means that it is only possible to send up to 4kBytes of data per transfer using normal mode, which is the simplest of the transfer methods. It is possible to circumvent this 4k limitation using the source chain transfer mode and this will be the subject of this tutorial.

 

 

Source Chain Mode

 

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.

 

The technique is illustrated in the example code provided with this tutorial. In the example, data is sent from main memory to scratchpad memory using source chain mode over DMAC channel 9.

 

 

DMA Tags

 

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 will be taken advantage of in later tutorials. For now, all of the top 64 bits are set to zero. The format and contents of the DMA Tag can be found on page 59 of the EE Users Manual. For now only QWC, ID, and ADDR are of interest.

 

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, each link has one DMA tag and associated data. This is similar to GIF tags and primitive data that was discussed previously. 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.

 

A comprehensive list of all the source chain tags can be found on page 46 of the EE Users Manual. The only tags that we can use on channel 9 are cnt, next, ref, refe, and end. The remaining ID’s will be discussed in a later tutorial. The table below gives an explanation of each of these tags.

 

Tag ID

Description

cnt

This tag says to transfer QWC of data following the tag, and then read the quad word after that 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.

ref

This tag says to transfer QWC of data from the address in the ADDR field. Then read the quad word following this tag as the next tag.

refe

Same as ref except that it ends the transfer 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.

 

All of these tags are used in the example code except for refe. After understanding this tutorial, try to change the last tag in the sample to a refe tag (be aware that this is not simply a case of changing the ID field).

 

The table below can be used to help understand what is going on in the source chain mode given in the example code. First the DMA chain is written to the SPS2 allocated memory. Once this is done the memory is laid out in a manner similar to that shown in the table (note that the addresses are relative to the start of the allocated memory):

 

In the example code, the DMA tags and data to be transferred are scattered around memory according to the table below.

 

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

 

Once initiated, the DMAC will run through this from address 0x0000 reading in DMA Tag #1. It will transfer the 2 quad words of string 1 to the scratchpad, and then read in DMA Tag #2 from the address in ADDR. DMA Tag #2 causes the DMAC to transfer the two quad words from the address in ADDR which is String 2, and then read in DMA Tag #3. This 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. Finally the DMAC transfers the final two quad words (string 4) and then ends the transfer. Therefore all the strings are transferred to the scratchpad in order, even though they are dotted all over main memory.

 

As hinted at in the introduction to this tutorial, source chain mode can be used to circumvent the 4k block allocation limitation. There are a few methods that can be used to achieve this, but as an example, for every 4 kilobytes block of data, a next tag can be put in the last qword that will point the DMAC to the start of the next 4k block to be transferred. This technique is known as “stitching” and will be covered in a later tutorial.

 

 

The Example Code

 

Now consider the example code that accompanies this tutorial. Initially some strings are defined and their length in qwords is calculated. SPS2 is initialised and some convenient pointers to the start of the allocated memory are obtained. Instances of the DMAC registers and the DMA tags to be used are then obtained. The four tag structures are then configured according to the format shown in the table above. All of the DMAC tags and the strings are then written to memory in the required order. Before any transfer is initiated, the cache is flushed to make sure all the memory is written (notice that cached memory it being used in this example).

 

Now the DMAC register are configured. Firstly the Scratchpad address register is set to zero which is the address in scratchpad RAM where the data is to be sent. Next the qword count (QWC) register is set to zero. It is worth noting that when the DMAC transfer is initiated with QWC=0, this will cause the DMAC to immediately load and execute the tag pointed to in the tag address register, which is the required action. The tag address register is set to point to the start of the SPS2 allocated memory which is the address of the first tag to be read. Finally, the channel control register is set up to be a chain mode transfer and the start bit is set to one to initiate the transfer. The instant the information in the channel control register structure is written into the channel control register the transfer will commence.

 

At this point the program must wait until the DMAC finishes the transfer, this being achieved by the sps2WaitForDMA() function.

 

In order to verify that the transfer has been successful, the strings are printed out to the console directly from scratchpad memory. SCRATCH_PAD is a constant with a value equal to the address of the start of scratchpad memory. (Note that the DMAC did not need to be used to transfer data to the scratchpad ram since a pointer to the scratchpad memory already exists (SCRATCH_PAD), but the program is constructed in this manner to illustrated the use of the DMAC Tags).

 

To end the program the allocated memory is freed and the SPS2 device is released.

 

 

Conclusions

 

This tutorial illustrated the source chain mode of the DMAC. This method will be used in future tutorials to build DMAC data chains which are larger than 4kBytes.

 

 

Dr Henry S Fortuna

University of Abertay Dundee

h.s.fortuna@abertay.ac.uk