Copyright © Acorn Computers Ltd. 1993       0197,275/FS Issue 2 ****LIVE****

              Medusa : DMA Software Functional Specification
              ==============================================

                -----------------------------------------
                | Drawing No : 0197,275/FS              |
                |      Issue : 2 ****LIVE****           |
                |       Date : 29th September 1993      |
                |     Author : Steve Cormie             |                
                |     Sheets :                          |
                | Change No. : AMR ????                 |
                | Last Issue : 1                        |
                -----------------------------------------

 * NOTE: see StrongARM file for change to DMA manager behaviour

Contents
--------

1.      History
2.      Outstanding Issues
3.      Overview
4.      Technical Background
        4.1     Logical and Physical DMA Channels
        4.2     Memory Manager Interfaces
5.      Programmer Interface
        5.1     SWIs
        5.2     Control Routines
6.      External Dependencies
7.      Development Test Strategy
8.      Organisation
9.      Historical Notes
        9.1     Page Locking
        9.2     Redundant Features
                9.2.1   SWIs DMA_ClaimChannel and DMA_ReleaseChannel
                9.2.2   SWI DMA_ExtendTransfer


1. History
----------

     JSR 25-Aug-92 Written
     JSR 25-Aug-92 Add new vector entry for sequence element getting
                   transferred.
                   Add example.
                   Add allocation of logical DMA channels
     JSR 25-Aug-92 Updated on input from DDV.
     JSR 28-Aug-92 Updated on input from MT and TD.
     JSR 08-Sep-92 Updated with cache control in mind.
                   Updated to allow control of DMA cycle speed.
     JSR 25-Sep-92 Changed method of scatter presentation to fixed length to
                   avoid difficulties with memory management.
                   Changed completion details to allow error passing.
     JSR 25-Sep-92 Issues section added.
                   Scatter list format added.
                   Suspend and resume transfer detailed out.
     SMC 22-Oct-92 Added transfer size to DMA_RegisterChannel flags.
                   Removed SWI DMA_CacheControl
0.00 SMC 09-Nov-92 Created from Jonathan Roach's spec.
0.01 SMC 17-Nov-92 Future proofed DMA_RegisterChannel interface.
0.02 SMC 18-Nov-92 Added more error checking.
0.03 SMC 24-Nov-92 Added SWI DMA_ExtendTransfer.
0.04 SMC 30-Nov-92 Minor mods, renamed some SWIs.
0.05 SMC 15-Dec-92 Fixed some mistakes.
0.06 SMC 05-Jan-93 Page locking no longer an issue.
                   Interfaces required with memory manager noted.
                   Updated to reflect use of IODC as crosspoint switch.
                   Overview expanded.
                   SWI chunk allocated.
                   DMA_QueueTransfer clarified and extended for circular
                        buffers and DMASync callback.
                   Flag added to DMA_ResumeTransfer.
                   DMA_ExtendTransfer clarified.
                   Added DMA_ClaimChannel and DMA_ReleaseChannel.
                   Added go/nogo return from Start callback.
                   Complete routine clarified.
                   Added DMASync callback.
                   Development test strategy extended.
                   Added comments on SWI re-entrancy.
                   Added SWI DMA_ExamineTransfer.
0.07 SMC 08-Jan-93 Modified DMA_QueueTransfer and DMASync callback.
0.08 SMC 20-Jan-93 Show supported logical channels.

Issue 1            AMR 3453             First release

1.00 SMC 24-Mar-93 Started changes to released Issue 1.
                   SWIs DMA_ClaimChannel and DMA_ReleaseChannel removed.
                   Bit 0 of DMA_ResumeTransfer flags not required.
                   Callbacks can be called in IRQ/SVC mode with IRQs on/off.
                   Error from Start callback passed back to SWI calls.
1.01 SMC 25-Mar-93 Changed references of Jordan to Medusa.
                   Added Historical Notes section.
                   Moved comments about IODC into Historical Notes section.
1.02 SMC 26-Mar-93 Added comments about returning from callbacks.
1.03 SMC 12-May-93 Removed SWI DMA_ExtendTransfer.
                   Added info on memory manager interfaces.
1.04 SMC 12-Jul-93 Corrected SWI numbers.
1.05 SMC 14-Jul-93 Corrected SWI numbers back again.

Issue 2            AMR ????             Second release

2.00 SMC 18-Oct-93 Detailed limitations of DMASync callback.
                   Don't call DMA manager SWIs from callbacks.

.end

2. Outstanding Issues
---------------------

There are no outstanding issues.


3. Overview
-----------

DMA is controlled by a (small) number of physical DMA channels (4 on
Medusa) and services a potentially large number of devices.  The DMA
module performs the necessary arbitration and switching between the devices
with help from the device drivers.  The DMA module also interfaces between a
general purpose software interface and the available hardware interface to
the DMA channels.  This isolates software from hardware to a sufficient
degree that changes to the hardware need only affect the DMA manager and
not DMA clients.  Memory mapping is handled by the DMA manager in
conjunction with the memory management module so that a DMA client need not
be concerned with the mapping of logical to physical addresses or if a page
is remapped during a DMA operation.

In general, a DMA client will register itself with the DMA manager as the
owner of a logical device and then request DMA transfers as and when
necessary.  The DMA manager will attempt to start the operation immediately
but if it cannot (eg. there are no free DMA channels) then the request will
be queued in a FIFO.  The request will only be started when it is at the
head of the queue and a DMA channel becomes free.  Because of the possible
time lag between requesting the operation and it actually starting the
client will provide a set of callback routines which the DMA manager will
call to keep the client up to date with the state of its operations.  The
DMA manager does not impose any priority on logical devices, requests are
handled first-come-first-served.

More advanced control is provided so that DMA requests can be suspended,
resumed, terminated and queried.


4. Technical Background
-----------------------

4.1 Logical and Physical DMA Channels

The DMA manager will control the following 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
4       Sound out
5       Sound in

These are termed physical DMA channels and the 4 general purpose physical
channels must be shared by several devices via logical channels.  The
following logical channels have been allocated:

Logical                         Physical
Channel Use                     Channel
&000    Podule 0, DMA line 0    2
&001    Podule 0, DMA line 1    *
&010    Podule 1, DMA line 0    3
&011    Podule 1, DMA line 1    *
&020    Podule 2, DMA line 0    *
&021    Podule 2, DMA line 1    *
&030    Podule 3, DMA line 0    *
&031    Podule 3, DMA line 1    *
&040    Podule 4, DMA line 0    *
&041    Podule 4, DMA line 1    *
&050    Podule 5, DMA line 0    *
&051    Podule 5, DMA line 1    *
&060    Podule 6, DMA line 0    *
&061    Podule 6, DMA line 1    *
&070    Podule 7, DMA line 0    *
&071    Podule 7, DMA line 1    *
&100    On-board SCSI           *
&101    On-board Floppy         1
&102    Parallel                1
&103    Sound out               4
&104    Sound in                5
&105    Network Card            0

The mapping between logical and physical DMA channels is fixed.  The logical
channels marked with a * above will not have DMA connected on Medusa and
have been assigned logical channel numbers for future use.

The four general purpose physical DMA channels may be connected to devices
on either side of the podule buffer.  In order to avoid confusion the podule
buffer must not be output enabled during DMA operations to internal
peripherals but must be enabled for DMA operations to external devices. The
DMA manager will use 4 bits in IOMD register DMAEXT to specify whether the
corresponding general purpose physical channel is mapped to an internal or
external device.


4.2 Memory Manager Interfaces

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

1) The DMA manager must map logical addresses to physical addresses so that
   the IOMD DMA registers can be programmed.  This will be done by creating
   a page table contining the logical addresses of all pages used in the
   transfer and calling SWI OS_Memory to fill in the corresponding physical
   addresses.

2) On a DMA transfer from device to memory the DMA manager must ask the
   memory manager to mark pages as uncacheable so that reads from the pages
   being DMAed into will return the transferred data and not cached data.
   This will be done in combination with the above SWI OS_Memory call.  The
   DMA manager will flush the cache after this call but before starting the
   transfer.

3) The memory manager will broadcast Service_PagesUnsafe when it is about to
   remap some physical pages ie. 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 must scan its page tables for all active transfers and
   temporarily halt any transfer which is transfering 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 can then continue any halted transfers
   using the new physical addresses.

See the Medusa Memory Management Software Functional Specification
(0197,276/FS) for more details.


5. Programmer Interface
-----------------------

Device drivers register with the DMA manager which logical channels
(devices) they control.  The device drivers then queue DMA requests which
the DMA manager processes in order.


5.1 SWIs

The following SWIs are provided for DMA control.

DMA_RegisterChannel     - registers a client device with the DMA manager.
DMA_DeregisterChannel   - opposite of above.
DMA_QueueTransfer       - queues a DMA transfer request.
DMA_TerminateTransfer   - terminates a DMA transfer request.
DMA_SuspendTransfer     - pauses an active DMA transfer.
DMA_ResumeTransfer      - restarts a paused DMA transfer.
DMA_ExamineTransfer     - return the progress of an active DMA transfer.


DMA_RegisterChannel (SWI &46140)
Registers a client device with the DMA manager.

On entry:       R0 = flags
                        bit     meaning
                        0-31    reserved (set to 0)
                R1 = logical channel
                R2 = DMA cycle speed (currently 0-3)
                R3 = transfer unit size (currently 1,2,4 or 16 bytes)
                R4 = vector of control routines
                R5 = value of R12 to be passed to control routines

On exit:        R0 = channel registration handle
                All other registers preserved

Interrupts:     Interrupt status is not altered
                Fast interrupts are enabled

Processor mode: Processor is in SVC mode

Re-entrancy:    SWI is not re-entrant

Use:            A device driver should call this SWI to register itself as
                the controller of the specified logical channel.  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 will be called by the DMA manager to control
                the specified logical channel.  They will be called with R12
                set to the value supplied in R5 which will usually be the
                device driver's workspace pointer.  See later for a full
                description of their use.

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


DMA_DeregisterChannel (SWI &46141)
Deregisters a device previously registered with DMA_RegisterChannel.

On entry:       R0 = channel registration handle

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 not re-entrant.

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

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


DMA_QueueTransfer (SWI &46142)
Queues a DMA transfer request for a logical channel.

On entry:       R0 = flags
                        bit     meaning
                        0       transfer direction
                                0 = from device to memory (read)
                                1 = from memory to device (write)
                        1       1 = scatter list is a circular buffer
                        2       1 = call "DMASync" callback
                        3-31    reserved (set to 0)
                R1 = channel registration handle
                R2 = value of R11 to be passed to control routines
                R3 = address of scatter list (word aligned)
                R4 = number of bytes to transfer
                   = 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 "DMASync" callbacks 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 request for a logical channel. The
                value in R2 will be quoted in R11 when the DMA manager calls
                any of the control routines and will usually describe 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 should not be remapped by the client 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 will be incremented and the length
                decremented to reflect how much data was transferred.  The
                DMA manager will then start a transfer for the next pair and
                repeat 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 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 SWI
                DMA_TerminateTransfer or by the DMASync callback.

                The value passed in R4 determines the number of bytes to be
                transferred.  If the transfer uses a circular buffer then
                this value can be 0 to indicate an infinite length transfer.
                This value must be a multiple of the transfer unit size and
                if a circular buffer is not used then it 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 should contain the number of
                bytes which are to be transferred between successive calls
                to the device drivers "DMASync" callback routine.  This is
                provided so that real-time synchronisation is possible for
                certain device drivers eg. sound.  The value in R6 must be a
                multiple of the transfer unit size.

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


DMA_TerminateTransfer (SWI &46143)
Terminates a DMA transfer request.

On entry:       R0 = pointer to 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 request queued by DMA_QueueTransfer.
                If the DMA request is active then it will be stopped and the
                DMA manager will call the "Disable DMA" control routine.
                Otherwise, the request is simply removed from its queue. The
                DMA manager will always call the "Completed" control routine
                with V set and R0 pointing to the supplied error block.

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

                An error will be returned if the DMA tag is invalid.


DMA_SuspendTransfer (SWI &46144)
Suspends an active DMA transfer.

On entry:       R0 = flags
                        bit     meaning
                        0       0 = don't start queued transfers
                                1 = start next queued transfer
                        1-31    reserved (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 will call the "Disable DMA" control routine, suspend
                the active DMA request, update the scatter list and return
                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 request is resumed or terminated.

                An error will be returned if the DMA tag is invalid or the
                specified DMA request is not in progress.


DMA_ResumeTransfer (SWI &46145)
Resume a previously suspended DMA transfer.

On entry:       R0 = flags
                        bit     meaning
                        0-31    reserved (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 position in the queue so a
                resumed transfer will have priority over requests queued
                after it was suspended.  The DMA manager will call the
                "Enable DMA" control routine when the suspended transfer is
                restarted.

                An error will be returned if the DMA tag is invalid or the
                transfer is restarted and the Start control routine returns
                an error.


DMA_ExamineTransfer (SWI &46146) Returns the progress of an active DMA
transfer.

On entry:       R0 = flags
                        bit     meaning
                        0-31    reserved (set to 0)
                R1 = DMA tag

On exit:        R0 = number of bytes transferred so far
                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 SWI returns the total number of bytes transferred by
                the specified active DMA operation.  An error will be
                returned if the DMA tag is invalid or the specified DMA
                operation is not active.


5.2 Control Routines

The vector of control routines registered with the DMA manager by a device
driver will be called as follows for a normal transfer.

        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 and
interrupt status as necessary but must return to the DMA manager by using
the instruction MOVS r15, r14 (or equivalent LDM).  This restores the
processor mode, interrupt status and flags 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 in order to return an
error.  Note that enabling interrupts in callback routines may have
undesirable effects and should be avoided.  Note also that calling DMA
manager SWIs from these callback routines is not advised and may cause
problems.  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

Interrupts:     Interrupt status is undefined
                Fast interrupt status is undefined

Processor mode: Processor is in IRQ or SVC mode

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


Disable DMA

On entry:       R11 = R2 from DMA_QueueTransfer call
                R12 = R5 from DMA_RegisterChannel call

On exit:        All registers preserved

Interrupts:     Interrupt status is undefined
                Fast interrupt status is undefined

Processor mode: Processor is in IRQ or SVC mode

Use:            The DMA manager will call this control routine to disable
                device DMA.  This may be called in mid transfer (eg. 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:        VS => R0 = pointer to error block
                All other registers preserved

Interrupts:     Interrupt status is undefined
                Fast interrupt status is undefined

Processor mode: Processor is in IRQ or SVC mode

Use:            The DMA manager will call this control routine before
                starting a new DMA request.  This call will only be made
                once for each DMA request, suspending and then resuming a
                transfer will 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" routine will then be called with the same
                error.  If this call returns with no error then the DMA
                manager will then call the "Enable DMA" control routine.


Completed

On entry:       R0 = 0 (VC) or points to error block (VS)
                R11 = R2 from DMA_QueueTransfer call
                R12 = R5 from DMA_RegisterChannel call

On exit:        All registers preserved

Interrupts:     Interrupt status is undefined
                Fast interrupt status is undefined

Processor mode: Processor is in IRQ or SVC mode

Use:            The DMA manager will call 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.  Possible errors include:

                        Error supplied to DMA_TerminateTransfer
                        Error returned from "Start" control routine
                        "DMA channel deregistered"
                        "Insufficient memory pages available"
                        "No readable memory at this address"

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


DMASync

On entry:       R11 = R2 from DMA_QueueTransfer call
                R12 = R5 from DMA_RegisterChannel call

On exit:        R0 = 0 for continue
                   = N for stop after N bytes
                All other registers preserved

Interrupts:     Interrupt status is undefined
                Fast interrupt status is undefined

Processor mode: Processor is in IRQ or SVC mode

Use:            This callback is provided for real-time synchronisation with
                DMA transfers.  This is essential for time critical device
                drivers such as that for sound where the driver has to know
                how far a transfer has progressed.  This callback will only
                be made if bit 2 of R0 was set in the DMA_QueueTransfer call
                and will be made after every transfer of the number of bytes
                specified in R6 in the same DMA_QueueTransfer call.  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*s+t bytes where s=gap between DMASync
                calls and t=transfer unit size.  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.


6. External Dependencies
------------------------

The DMA manager can not be fully tested until the EASI bus development card
becomes available.  This card has on board RAM which can be DMAed into and
out of and will be used for directed testing.


7. Development Test Strategy
----------------------------

A DMA module basher written in BASIC will test the SWIs and control routines
randomly.  It will ensure that errors are returned when expected, control
routines are called at appropriate times and no registers are corrupted.

Directed tests will be developed to test special cases including:

a) Transfers which cross page boundaries.
b) Transfers which start/end on page boundaries.
c) Zero length transfers.
d) Zero length scatter list entries.
e) Pages being remapped during transfers.
f) Suspended then resumed transfers.
g) Devices on either side of the podule buffer.

In each case the validity and continuity of the data which is transferred
will be checked.

A test podule is already being developed which amongst other things will
simulate a DMA device.  The podule will also have an amount of RAM which can
be DMAed to or from so that validity checks can be made.


8. Organisation
---------------

The DMA manager module will be included in the RISC OS ROM.  All test
software and expected results will be fully documented and will reside in a
Test directory with the DMA module sources.


9. Historical Notes
-------------------

9.1 Page Locking

This section is no longer relevant as the OS for Medusa will not support
virtual memory.  The text will remain as a historical note and it should be
noted that the recommended solution for page locking was agreed to be 1 (DMA
manager locks pages).

It is not yet agreed where the page locking activity should reside in a
memory management architecture.  Page locking is the act of ensuring a
physical address space page is always available for a virtual address.  The
arguments for and against are presented here with consideration for the
architecture:

Application -> FileSwitch -> SCSIFS -> SCSIDriver -> DMA

1) Locked by DMA manager.
        + One thing does the locking.
        + Old clients of DMA-requiring services will continue to work where
                otherwise they might fail unexpectedly.
        - The DMA manager cannot break up an operation to be memory manager
                friendly.

2) Locked by SCSIDriver.
        + Old clients continue to work.
        - Some device drivers cannot break up operations.

3) Locked by SCSIFS.
        + Operation can be broken up to be memory manager friendly.
        - Locks SCSIFS into being Medusa dependant.
        - May lock unnecessarily (the device driver may not need DMA).

4) Locked by FileSwitch.
        + All file systems benefit.
        + Operation can be broken up.
        - Lock may be unnecessary and harmful (eg. RAMFS).

It is suggested that for Medusa the DMA manager locks memory.  For future
OS development (eg. Gold) locking can be performed at a higher level too, no
harm occurs as a double-locked page is still locked.  This means least work
and least Medusa-dependant modules.


9.2 Redundant Features

9.2.1 SWIs DMA_ClaimChannel and DMA_ReleaseChannel

The intention in project Jordan was to use a new ASIC (IODC) to map logical
devices to physical DMA channels dynamically, hence any device could use any
one of the four general purpose DMA channels.  After the project was
rationalised and became project Medusa it was decided that IODC would not be
implemented and that logical devices would be permanently wired to physical
DMA channels. This meant that the following two SWIs were made redundant and
were not implemented in the DMA manager.

DMA_ClaimChannel
Claim a physical DMA channel for the sole use of a logical device.

On entry:       R0 = flags
                        bit     meaning
                        0       0 = claim any channel
                                1 = claim channel specified in R2
                        0-31    reserved (set to 0)
                R1 = channel registration handle
                bit 0 set in R0 => R2 = physical channel to claim (0-3)

On exit:        R2 = physical channel claimed (0-3)
                All registers preserved

Interrupts:     Interrupt status is not altered
                Fast interrupts are enabled

Processor mode: Processor is in SVC mode

Re-entrancy:    SWI is re-entrant

Use:            This SWI can be used to reserve one of the 4 general purpose
                physical DMA channels for the sole use of the specified
                logical channel.  This may be necessary for device drivers
                waiting for input eg. an Ethernet driver waiting for input
                packets which it does not want to lose.

                If bit 0 of R0 is clear then the SWI will return the number
                of the claimed channel (0-3) in R2.  If the bit is set then
                the channel specified in R2 will be claimed.

                If the device has a transfer active on another channel or
                if a DMA transfer is currently active on the claimed channel
                then any pending requests for the logical device will wait
                until that channel becomes free ie. the channel cannot be
                assumed to be claimed until the "Start" control routine for
                the logical device is next called.

                A physical DMA channel should only be claimed for as short a
                time as is necessary as it restricts the number of channels
                available for other devices and may affect the performance
                of the system.

                An error will be returned if the channel registration handle
                is invalid, the specified channel is invalid or another
                device has already claimed the specified channel.


DMA_ReleaseChannel
Release a previously claimed physical DMA channel.

On entry:       R0 = physical channel claimed (0-3)
                R1 = channel registration handle

On exit:        All registers preserved

Interrupts:     Interrupt status is not altered
                Fast interrupts are enabled

Processor mode: Processor is in SVC mode

Re-entrancy:    SWI is re-entrant

Use:            This SWI is called to release a previously claimed physical
                DMA channel.  An error will be returned if the channel
                registration handle is invalid, the physical channel number
                is invalid or the channel has not been claimed.


9.2.2 SWI DMA_ExtendTransfer

SWI DMA_ExtendTransfer was originally requested by Mark Taunton for the new
sound system on Jordan (using a CODEC).  On further thought he decided that
this SWI did not provide the functionality he required and requested that
the DMA manager be extended to provide circular buffers.  This was done but
DMA_ExtendTransfer was left in the specification even though it was no
longer needed.  With the introduction of code for the new memory manager
interfaces it quickly became clear that it would be difficult and
inefficient to support this SWI therefore it has been removed from the
specification.

Note that this also prevents a DMA client from getting onto a physical DMA
channel and blocking it by continuously extending a transfer (something the
original specification required).


DMA_ExtendTransfer
Extend an active DMA transfer.

On entry:       R0 = flags
                        bit     meaning
                        0-31    reserved (set to 0)
                R1 = DMA tag
                R2 = additional scatter list pointer (word aligned)
                R3 = length of additional transfer (in bytes)

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 extends the specified DMA request by the given
                length and additional scatter list.  This is provided for
                device drivers which really need to do indeterminate length
                transfers.

                A DMA request can be extended before or during the transfer
                and extensions are double-buffered ie. there can only be one
                extension pending at any one time but when the extension is
                started a new extension can be specified.

                An error will be returned if the DMA tag is invalid, the
                length is not a multiple of the transfer unit size or the
                transfer cannot be extended.
