www.riscos.com Technical Support: |
|
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.
The DMA manager:
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.
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 |
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.
The DMA manager and the memory manager interface in the following ways:
See the chapter entitled Memory management for more details.
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.
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:
R11 = R2 from DMA_QueueTransfer call
R12 = R5 from DMA_RegisterChannel call
All registers preserved
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.
R11 = R2 from DMA_QueueTransfer call
R12 = R5 from DMA_RegisterChannel call
All registers preserved
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.
R11 = R2 from DMA_QueueTransfer call
R12 = R5 from DMA_RegisterChannel call
V set R0 = pointer to error block
All other registers preserved
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.
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
All registers preserved
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'
R11 = R2 from DMA_QueueTransfer call
R12 = R5 from DMA_RegisterChannel call
R0 = 0 to continue, or n to stop after n bytes
All other registers preserved
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.
Registers a client device as the controller of a logical channel
R0 = flags:
R0 = channel registration handle
R1 - R5 preserved
Interrupt status is not altered
Fast interrupts are not altered
Processor is in SVC mode
SWI is not re-entrant
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.
Deregisters a client device previously registered by DMA_RegisterChannel
R0 = channel registration handle
R0 preserved
Interrupts may be disabled
Fast interrupts are not altered
Processor is in SVC mode
SWI is not re-entrant
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.
None
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)
R0 = DMA tag
All other registers preserved
Interrupts may be disabled
Fast interrupts are not altered
Processor is in SVC mode
SWI is re-entrant
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:
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.
R0 = pointer to an error block
R1 = DMA tag
All registers preserved
Interrupts may be disabled
Fast interrupts are not altered
Processor is in SVC mode
SWI is re-entrant
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.
R0 = flags:
bit 0 | clear don't start queued transfers set start next queued transfer |
bits 1-31 | reserved (must be set to 0) |
All registers preserved
Interrupts may be disabled
Fast interrupts are not altered
Processor is in SVC mode
SWI is re-entrant
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.
R0 = flags:
R1 = DMA tag
All registers preserved
Interrupts may be disabled
Fast interrupts are not altered
Processor is in SVC mode
SWI is re-entrant
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.
None
R0 = flags:
R1 = DMA tag
R0 = number of bytes transferred so far
All other registers preserved
Interrupt status may be disabled
Fast interrupts are not altered
Processor is in SVC mode
SWI is re-entrant
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.
None