RISCOS.com

www.riscos.com Technical Support:
Programmer's Reference Manual

 

DMA


Introduction and Overview

From RISC OS 3.5 onwards, support for DMA (direct memory access) is provided by the new DMAManager module. However, some computers' hardware will not support DMA, in which case the DMA manager becomes dormant.

The DMA (Direct Memory Access) is controlled by four DMA channels; these service a potentially large number of devices.

DMA manager

The DMA manager:

  • Performs the arbitration and switching between devices (with help from the device drivers).
  • Provides a general purpose software interface to the DMA channels' available hardware interface.
  • Isolates software from hardware so that changes to the hardware do not affect DMA clients - just the DMA manager.
  • Handles memory mapping and memory management, so that any DMA clients are not concerned with logical to physical addresses or if a page is remapped during a DMA operation.

A DMA client registers itself with the DMA manager as the owner of a logical device. It then requests DMA transfers as and when necessary.

The DMA manager processes the requests on a first-come-first-served basis; it does not impose any priority on logical devices. It attempts to start the transfer as soon as possible. If the required DMA channel is not free, the request is stored in a FIFO queue. The request then starts when it is at the head of the queue and the required DMA channel is free.

The DMA manager provides a set of callback routines to keep the client up-to-date on the state of its operations; this is because of the possible time-lag between requesting and starting an operation.

DMA requests can be suspended and resumed, examined and terminated.

Technical details

Logical and physical DMA channels

The DMA manager controls the following physical DMA channels provided by IOMD:

0 General purpose channel 0
1 General purpose channel 1
2 General purpose channel 2
3 General purpose channel 3

The four general purpose physical channels must be shared by several devices via logical channels. The following logical channels are supported:

Logical channel Use Physical channel
&000 Expansion card 0, DMA line 0 2
&001 Expansion card 0, DMA line 1
&010 Expansion card 1, DMA line 0 3
&011 Expansion card 1, DMA line 1
&020 Expansion card 2, DMA line 0
&021 Expansion card 2, DMA line 1
&030 Expansion card 3, DMA line 0
&031 Expansion card 3, DMA line 1
&040 Expansion card 4, DMA line 0
&041 Expansion card 4, DMA line 1
&050 Expansion card 5, DMA line 0
&051 Expansion card 5, DMA line 1
&060 Expansion card 6, DMA line 0
&061 ‘ Expansion card 6, DMA line 1
&070 Expansion card 7, DMA line 0
&071 Expansion card 7, DMA line 1
&100 On-board SCSI
&101 On-board Floppy
&102 Parallel
&103 Sound out
&104 Sound in
&105 Network card 0
Mapping between logical and physical channels

The mapping between logical and physical channels is fixed. Logical channels with no mapping shown above do not have DMA connected or are not controlled by the DMA Manager, and the numbers they have been assigned are for future use only.

The four general purpose physical DMA channels can be connected to devices on either side of the expansion card buffer. To avoid confusion, the expansion card buffer is not output enabled during DMA operations to internal peripherals, but is enabled for DMA operations to external devices. The DMA manager uses four bits in the IOMD register DMAEXT to specify whether the corresponding general purpose physical channel is mapped to an internal or external device.

Memory manager interfaces

The DMA manager and the memory manager interface in the following ways:

  1. The DMA manager maps logical addresses to physical addresses so that the IOMD DMA registers can be programmed. It does so by creating a page table containing the logical addresses of all pages used in the transfer, and then calling OS_Memory (see OS_Memory) to get the memory manager to fill in the corresponding physical addresses.
  2. On a DMA transfer from device to memory the DMA manager calls OS_Memory to ask the memory manager to mark the pages being DMAed into as uncacheable. This is so that reads from these pages return the transferred data rather than cached data. The DMA manager flushes the cache after making this call, but before starting the transfer. It makes the pages cacheable again once the transfer has completed.
  3. The memory manager broadcasts Service_PagesUnsafe when it is about to remap some physical pages (i.e. when the physical addresses which correspond to a range of logical addresses are about to change). This service call provides a page table of the same form as that used in the OS_Memory interface which contains the physical addresses of the unsafe pages. The DMA manager then scans its page tables for all active transfers and temporarily halts any transfer which is transferring to or from an unsafe page. After the pages have been remapped the memory manager broadcasts Service_PagesSafe which provides the new physical addresses for the unsafe pages. The DMA manager then continues any halted transfers using the new physical addresses.

See the chapter entitled Memory management for more details.

Device drivers

Device drivers call DMA_RegisterChannel to register with the DMA manager which logical channels (devices) they control. The device drivers then call DMA_QueueTransfer to place DMA requests on a queue which the DMA manager processes in order. There are calls to terminate a transfer (DMA_TerminateTransfer), suspend a transfer (DMA_SuspendTransfer) and resume it (DMA_ResumeTransfer), and to examine the state of a transfer (DMA_ExamineTransfer). If a device wishes to relinquish control of a logical channel, it should do so by calling DMA_DeregisterChannel.

Control routines

When a device driver calls DMA_RegisterChannel it passes a pointer to a word aligned table of control routine addresses. These control routines are called by the DMA manager during DMA; for a normal transfer the sequence is:

Start
Enable DMA
        transfer
        ...
        transfer
Disable DMA
Completed

The control routines will be called in IRQ or SVC mode with interrupts enabled or disabled.

A control routine may alter processor mode as necessary. If interrupts are disabled on entry a control routine must neither enable interrupts, nor should it call DMA manager SWIs, as either may cause undesirable side effects. If interrupts are enabled on entry a control routine may change interrupt state and call DMA manager SWIs. On exit a control routine must restore the processor mode, interrupt status and processor flags (ie by using the instruction MOVS R15, R14 or an equivalent LDM), so that the DMA manager may continue where it left off. The only exception to this is that the Start control routine may alter the status of the V flag to indicate an error.

The control routines must conform to the following interfaces:

Enable DMA
On entry

R11 = R2 from DMA_QueueTransfer call
R12 = R5 from DMA_RegisterChannel call

On exit

All registers preserved

Use

The DMA manager calls this control routine to enable device DMA before starting the DMA transfers. It is assumed that the default state is for device DMA to be disabled.

Disable DMA
On entry

R11 = R2 from DMA_QueueTransfer call
R12 = R5 from DMA_RegisterChannel call

On exit

All registers preserved

Use

The DMA manager calls this control routine to disable device DMA. This may be called in mid transfer (for example, if DMA_TerminateTransfer or DMA_SuspendTransfer is called), or when a DMA request has completed.

Start
On entry

R11 = R2 from DMA_QueueTransfer call
R12 = R5 from DMA_RegisterChannel call

On exit

V set => R0 = pointer to error block
All other registers preserved

Use

The DMA manager calls this control routine before starting a new DMA request. This call is only made once for each DMA request; suspending and then resuming a transfer does not call this routine again. If the device driver no longer wants this operation to start then it should return with V set and R0 pointing to an error block; the Completed control routine is then called with the same error. Otherwise, the DMA manager then calls the Enable DMA control routine.

Completed
On entry

R0 = 0 (if V is clear) or pointer to error block (if V is set)
R11 = R2 from DMA_QueueTransfer call
R12 = R5 from DMA_RegisterChannel call

On exit

All registers preserved

Use

The DMA manager calls this control routine when a DMA request has completed. The Disable DMA control routine will have been called and the scatter list brought fully up to date before this routine is called. If the V flag is clear then the DMA request has completed successfully. Otherwise, the DMA request has terminated prematurely due to an error.

As soon as this control routine is called the DMA tag for the completed operation is no longer valid.

Possible errors include:

Error supplied to DMA_TerminateTransfer
Error returned from 'Start' control routine
'DMA channel deregistered'

DMASync
On entry

R11 = R2 from DMA_QueueTransfer call
R12 = R5 from DMA_RegisterChannel call

On exit

R0 = 0 to continue, or n to stop after n bytes
All other registers preserved

Use

The DMA manager optionally calls this control routine after a fixed number of bytes have been transferred. The calling of this routine is configured when your device driver calls DMA_QueueTransfer (see DMA_QueueTransfer) to queue a request for DMA transfer.

This routine allows for real-time synchronisation with DMA transfers, which is essential for time critical device drivers where the driver has to know how far a transfer has progressed.

If the device driver wants the transfer to stop then a non-zero value can be returned in R0 which specifies how many more bytes to transfer. Note that the DMA manager will attempt to stop after the specified number of bytes, but that this may not be possible because the next two sections of the transfer may have been initiated already. This means that the transfer might continue for at most

(2 × gap between DMASync calls + transfer unit size) bytes

If a number greater than or equal to this is returned by DMASync then the transfer is guaranteed to stop after the specified number of bytes.

SWI calls


DMA_RegisterChannel
(SWI &46140)

Registers a client device as the controller of a logical channel

On entry

R0 = flags:

bits 0 - 31 reserved (must be set to 0)
R1 = logical channel
R2 = DMA cycle speed (0 - 3)
R3 = transfer unit size (1, 2, 4 or 16 bytes)
R4 = pointer to table of control routine addresses
R5 = workspace pointer to be passed to control routines in R12

On exit

R0 = channel registration handle
R1 - R5 preserved

Interrupts

Interrupt status is not altered
Fast interrupts are not altered

Processor mode

Processor is in SVC mode

Re-entrancy

SWI is not re-entrant

Use

This call registers a client device as the controller of a logical channel; it is typically called by a device driver. The value passed in R4 is a pointer to a word aligned table of control routine addresses:

Routine Use
R4 + 0 Enable device DMA
R4 + 4 Disable device DMA
R4 + 8 Start
R4 + 12 Completed
R4 + 16 DMASync

These routines are called by the DMA manager to control the specified logical channel. They are called with R12 set to the value supplied in R5, which is usually the device driver's workspace pointer. For a full description of their use, see the chapter entitled Control routines.

An error is returned if the logical channel is invalid or has already been claimed, an invalid cycle speed or transfer size is specified, or the control routine table is not word aligned.

This call is only available from RISC OS 3.5 onwards.

Related SWIs

DMA_DeregisterChannel

Related vectors

None


DMA_DeregisterChannel
(SWI &46141)

Deregisters a client device previously registered by DMA_RegisterChannel

On entry

R0 = channel registration handle

On exit

R0 preserved

Interrupts

Interrupts may be disabled
Fast interrupts are not altered

Processor mode

Processor is in SVC mode

Re-entrancy

SWI is not re-entrant

Use

This call deregisters a client device previously registered with the DMA manager by DMA_RegisterChannel. Before the device is deregistered all DMA transfers will be terminated on the logical channel it is controlling.

An error is returned if the channel registration handle passed in R0 is invalid.

This call is only available from RISC OS 3.5 onwards.

Related SWIs

DMA_RegisterChannel

Related vectors

None


DMA_QueueTransfer
(SWI &46142)

Queues a DMA transfer request for a logical channel

On entry

R0 = flags:

bit 0 set => write (i.e. from memory to device)
clear => read (i.e. from device to memory)
bit 1 set => scatter list is a circular buffer
clear => not circular
bit 2 set => call DMASync control routine
clear => don't call
bits 3 - 31 reserved (must be set to 0)

R1 = channel registration handle
R2 = value of R11 to be passed to control routines
R3 = pointer to word-aligned scatter list
R4 = number of bytes to transfer, or 0 for infinite length transfer (if bit 1 of R0 set)
R5 = size of circular buffer (if bit 1 of R0 set)
R6 = number of bytes between calls to DMASync control routine (if bit 2 of R0 set)

On exit

R0 = DMA tag
All other registers preserved

Interrupts

Interrupts may be disabled
Fast interrupts are not altered

Processor mode

Processor is in SVC mode

Re-entrancy

SWI is re-entrant

Use

This call queues a DMA transfer request for a logical channel. The value in R2 is quoted in R11 when the DMA manager calls any of the control routines, and it describes the particular device/controller/transfer.

The scatter list is a word aligned table of (address, length) pairs, in that order:

  • Both address and length are 32-bit values and are word aligned.
  • The addresses are logical addresses which the client should not remap before the transfer is complete.
  • The lengths are in bytes and are assumed to be a multiple of the transfer unit size specified when the logical device was registered.

When the transfer specified by a scatter list entry pair has completed the address is incremented and the length decremented to reflect how much data was transferred. The DMA manager then starts a transfer for the next pair and repeats until the total number of bytes specified in R4 have been transferred.

If bit 1 of R0 is set then the scatter list is treated as a circular buffer. This means that the scatter list will not be updated as described above, and will instead wrap at the end to start again at the beginning. In this case the transfer may be of infinite length, so R5 contains the size of the buffer. Transfers using circular buffers can be suspended and resumed, and can be terminated explicitly by calling DMA_TerminateTransfer or by the DMASync control routine.

The value passed in R4 determines the number of bytes to be transferred, which must be a multiple of the transfer unit size. If the transfer uses a circular buffer then this value can be 0 to indicate an infinite length transfer. If the transfer doesn't use a circular buffer then this value must be less than or equal to the sum of the lengths of all scatter list entries.

If bit 2 of R0 is set then R6 contains the number of bytes which are to be transferred between successive calls to the device driver's DMASync control routine; again this value must be a multiple of the transfer unit size. This transfer method allows real-time synchronisation.

An error is returned if the channel registration handle is invalid, the scatter list is not word aligned, the length or the value in R5 or R6 (if either is used) is not a multiple of the transfer unit size, or the transfer is activated and the Start control routine returns an error.

This call is only available from RISC OS 3.5 onwards.

Related SWIs

DMA_TerminateTransfer

Related vectors

None


DMA_TerminateTransfer
(SWI &46143)

Terminates a DMA transfer

On entry

R0 = pointer to an error block
R1 = DMA tag

On exit

All registers preserved

Interrupts

Interrupts may be disabled
Fast interrupts are not altered

Processor mode

Processor is in SVC mode

Re-entrancy

SWI is re-entrant

Use

This call terminates a DMA transfer originally queued by DMA_QueueTransfer.

If the DMA transfer is active then it is stopped, and the DMA manager calls the Disable DMA control routine; otherwise, the request is simply removed from its queue. The DMA manager then calls the Completed control routine (on Completed) with V set and R0 pointing to the supplied error block.

If the terminated DMA transfer request was blocking a logical channel (i.e. had been suspended by a call to DMA_SuspendTransfer with bit 0 of R0 clear), then the logical channel is unblocked and its queued transfers are started again.

An error is returned if the DMA tag is invalid.

This call is only available from RISC OS 3.5 onwards.

Related SWIs

DMA_QueueTransfer

Related vectors

None


DMA_SuspendTransfer
(SWI &46144)

Suspends the given active DMA transfer

On entry

R0 = flags:

bit 0 clear => don't start queued transfers
set => start next queued transfer
bits 1-31 reserved (must be set to 0)
R1 = DMA tag
On exit

All registers preserved

Interrupts

Interrupts may be disabled
Fast interrupts are not altered

Processor mode

Processor is in SVC mode

Re-entrancy

SWI is re-entrant

Use

This call suspends the given active DMA transfer. The DMA manager calls the Disable DMA control routine, suspends the active DMA request, updates the scatter list and returns the request to a queue. If bit 0 of R0 is clear then no DMA requests for the same logical channel will be started until the suspended transfer is resumed or terminated.

An error is returned if the DMA tag is invalid, or the specified DMA transfer is not in progress.

This call is only available from RISC OS 3.5 onwards.

Related SWIs

DMA_ResumeTransfer

Related vectors

None


DMA_ResumeTransfer
(SWI &46145)

Resume a previously suspended DMA transfer

On entry

R0 = flags:

bits 0 - 31 reserved (must be set to 0)

R1 = DMA tag

On exit

All registers preserved

Interrupts

Interrupts may be disabled
Fast interrupts are not altered

Processor mode

Processor is in SVC mode

Re-entrancy

SWI is re-entrant

Use

This call resumes a previously suspended DMA transfer. A suspended transfer maintains its positions in the queue, so a resumed transfer has priority over requests queued after it was suspended. The DMA manager calls the Enable DMA control routine when the suspended transfer is restarted.

An error is returned if the DMA tag is invalid, or the buffer is not suspended.

This call is only available from RISC OS 3.5 onwards.

Related SWIs

DMA_SuspendTransfer

Related vectors

None


DMA_ExamineTransfer
(SWI &46146)

Returns the progress of a DMA transfer

On entry

R0 = flags:

bits 0 - 31 reserved (must be set to 0)

R1 = DMA tag

On exit

R0 = number of bytes transferred so far
All other registers preserved

Interrupts

Interrupt status may be disabled
Fast interrupts are not altered

Processor mode

Processor is in SVC mode

Re-entrancy

SWI is re-entrant

Use

This call returns progress of a DMA transfer, giving the total number of bytes transferred.

An error is returned if the DMA tag is invalid.

This call is only available from RISC OS 3.5 onwards.

Related SWIs

None

Related vectors

None

This edition Copyright © 3QD Developments Ltd 2015
Last Edit: Tue,03 Nov 2015