home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Hack-Phreak Scene Programs
/
cleanhpvac.zip
/
cleanhpvac
/
FAQSYS18.ZIP
/
FAQS.DAT
/
DMA_API.TXT
< prev
next >
Wrap
Text File
|
1990-07-16
|
33KB
|
1,004 lines
Virtual DMA Services (VDS)
Version 1.00
Printed July 16, 1990
Table Of Contents
Introduction..............................................1
Notes For Writing DMA Device Drivers......................2
Notes For DMA Service Environments........................3
Services..................................................6
Reserved Subfunctions.................................7
Get Version...........................................8
Lock DMA Region.......................................9
Unlock DMA Region....................................11
Scatter/Gather Lock Region...........................12
Scatter/Gather Unlock Region.........................14
Request DMA Buffer...................................15
Release DMA Buffer...................................16
Copy Into DMA Buffer.................................17
Copy Out Of DMA Buffer...............................18
Disable DMA Translation..............................19
Enable DMA Translation...............................20
Summary of Error Codes and Option Flags..................21
.End Table C.
INTRODUCTION
DOS device drivers which perform DMA, program a controller
with an address of a buffer region. All software running in
protected mode environments, whether running in virtual 8086
mode or in protected mode under a DOS extender, usually can
not determine the physical address of their DMA region. The
DMA controller also places further restrictions upon
acceptable DMA regions: they must be in contiguous physical
memory, on XTs they must be in the first 1Mb of memory and
on XTs, ATs and compatibles they must not cross 64Kb or
128Kb alignment boundaries. These services provide the
necessary support to allow a device driver or application
program to obtain the necessary information to program a DMA
transfer using either the on board DMA controller or a
busmaster DMA controller.
The services are provided through software interrupt 4Bh.
Programs must examine bit five (5) of the byte at
0040:007Bh. If the bit is set then they should use the DMA
services. Otherwise, the device can assume that all memory
is mapped linear = physical (probably running in real mode,
this can be a dangerous assumption, if the machine is
actually running in virtual mode, because the protected mode
software may not support this specification, and there is
not a method for checking for physical = linear).
An implementation of the DMA services must provide either
automatic remapping of pages to force regions of memory to
be physically contiguous or support a DMA buffer with a
minimum size of 16K, if paging is enabled by the system
software. Most 286 software can get by without supporting
either option.
With the exception of the AX register and unless otherwise
specified, all registers and flags are preserved across DMA
service calls. The AX register contents are undefined on
return unless the carry flag is set in which case AL
contains an error code.
NOTES FOR WRITING DMA DEVICE DRIVERS
DMA devices that use these services must continually monitor
bit five (5) of the byte at 0040:007Bh before programming
DMA. The services may be initialized or turned off at any
time.
For example, when a program begins using simulated expanded
memory a "LIMulator" will place the machine in Virtual 8086
mode and enable the DMA services. When all LIM memory has
been deallocated it will return the machine to real mode and
turn off the DMA services.
Note also that the type of DMA support provided may change
dynamically. For example, the user may run one protected
mode environment, exit it, and then run another protected
mode environment. In this case the services will be
provided by two different implementations.
There are various levels of support that device drivers can
have for DMA. These options are listed below in order from
best to worst:
Support scatter/gather on the hardware adaptor
Break DMA requests up in software so that a buffer is
never required
Break up DMA into 16K or smaller pieces so the default
buffer can be used
Force the user to override the buffer size
The last option is really not acceptable. At the very least
your software should chop up transfers into 16K pieces. For
example, it is acceptable to break hard disk transfers at
track boundaries. A normal hard disk track will fit into a
16K buffer.
DMA devices that are not as timing sensitive as disk drives
should break up transfers. Ideally, all DMA adaptors would
support scatter/gather in hardware.
In some situations a device driver has a real physical
address that it wants to use in a DMA transfer. These
physical addresses may be from memory allocated through XMS
or INT 15h before DMA services were provided, or may be for
memory that exists on an adapter card, etc. In these
situations, DMA lock calls should not be called, because the
service routines must interpret region addresses as linear
addresses. It is necessary, however to call the
Disable/Enable Translation services, if the standard DMA
controller is used for the transfer.
By convention, a buffer ID of zero in the DDS indicates that
no buffer has been allocated. Device driver software can
check this field to determine if a buffer was allocated.
NOTES FOR IMPLEMENTING DMA SERVICES
The recommended method of supporting these services is to
use a DMA buffer since it has been found to be faster than
attempting to remap memory on 386 machines. On 286 machines
it is possible to not implement a buffer; on these machines
the software calling the services must already know how to
split up transfers to deal with crossing alignment
boundaries. It is necessary to return the "No buffer
available" error (04h) for the Request DMA Buffer service
(07h).
All implementations of these services should provide
mechanisms for overriding the size of the DMA buffer or
remap region. Also, all implementations should provide a
mechanism for forcing the buffer or remap region to reside
in the first megabyte of physical memory. The actual
mechanism for doing this will be implementation dependent.
For example, some programs may use a configuration file
while others could use command line switches.
Lock calls for memory which is not "owned" by the provider
of these DMA services, memory allocated before the provider
started running including low memory, EBIOS data area and
extended memory allocated through INT 15h or XMS, must not
fail. If auto-remapping is supported, then pages must be
remapped to force contiguous regions. If auto-remapping is
not supported, then it is necessary for the provider to keep
these memory areas contiguous. Additionally, in some
environments, device drivers will exist which attempt long
term DMA transfers. In these environments it is necessary
to allow the user to configure the software so that such
transfers can take place. One solution is to force long
term DMA device drivers to be loaded after the provider
software. The other solution is to keep all "unowned"
memory mapped at the original location so linear equals
physical; this allows transfers started prior to DMA
services being provided to continue as normal.
Since other hardware/software services can be provided on
the INT 4Bh chain, it is necessary for provider software to
determine if they should chain interrupts when AH is not
81h. On Micro Channel machines this can be done by
examining bit three (3) in the byte at 0040:007Bh, if the
bit is set, then chaining is required, if it is clear, then
it is necessary to examine the vector contents. If the
vector contents are 0, or point to E000h or F000h ROM, then
the interrupt should not be chained, because it may go to a
default IRQ handler which may EOI an outstanding hardware
interrupt. Summary of bit 3 in 0040:007Bh:
Bit 3 Interrupt 4Bh Intercepted Indicator (Micro
Channel Only)
= 0 Interrupt vector not intercepted. check contents
of the interrupt vector. If contents are 0:0 or
segment values of E000h or F000h, chaining is not
permitted.
= 1 Interrupt vector intercepted, chaining required.
On other non-Micro Channel architectures examining the
vector value may be the only way to determine if interrupts
should be chained.
If not chaining, then the interrupt should be ignored with
an IRET without modifying registers or flags.
Determining Which Error Codes to Return
The following logic should be used for the Lock DMA Region
service (AX=8103h):
IF region contiguous THEN
IF region does not cross alignment boundary THEN
Lock region, set buffer ID to zero, and return
with carry clear
ELSE
DO Buffer/Remap
ENDIF
ELSE
DO Buffer/Remap
ENDIF
BUFFER/REMAP:
IF buffer supported THEN
IF buffer disable flag clear THEN
DO Buffer
ELSE
Return with carry flag set and AL=1, 2, or 3
ENDIF
ELSE
IF remap supported THEN
IF remap disable flag clear THEN
DO Remap
ELSE
Return with carry flag set and AL=1, 2, or 3
ENDIF
ELSE
Return with carry flag set and AL=1, 2, or 3
ENDIF
ENDIF
BUFFER:
IF buffer available THEN
IF region size <= buffer size THEN
Allocate buffer
IF copy flag set THEN
Copy data from linear region to buffer
ENDIF
Set buffer ID (non-zero), set physical address
field to buffer physical address, and return
with carry clear
ELSE
Return with carry flag set and AL=05h
ENDIF
ELSE
Return with carry flag set and AL=06h
ENDIF
REMAP:
IF region can be forced contiguous THEN
IF region will not cross specified boundary THEN
Force region contiguous, set physical address
field, set buffer ID to zero, and return with
carry clear
ELSE
Return with carry set and AL=02h
ENDIF
ELSE
Return with carry set and AL=01h
ENDIF
SERVICES
Most services take a pointer to a DMA descriptor structure
(DDS) as a parameter. The structure is defined as follows:
DESCRIPTION OFFSET
Region Size 00h
Offset 04h
Buffer ID Segment/Selector 08h
Physical Address 0Ch
Region Size is a dword at offset 0. It specifies the size
of the DMA region in bytes.
Offset and Segment/Selector are an fword pair at offset 04h.
They specify a 48-bit segment:offset pointer for
virtual 8086 mode, or a selector:offset pointer for
protected mode programs. Note that if the linear
address has already been determined then you may set
the segment/selector field to 0 and place the linear
address in the linear offset field. It is possible to
specify 32-bit offsets, even with real mode segment
values; this makes it much easier for device drivers to
split up DMA transfers, by simply modifying the offset
without having to modify the segment/selector.
Buffer ID is a word at offset 0Ah. This field is filled in
by the Request DMA Buffer service and possibly the Lock
DMA Region service.
Physical Address is a dword at offset 0Ch. This field is
filled in by the Lock DMA Region and Request DMA Buffer
services.
============================================================
Reserved Subfunctions
Functions 00h, 01h and 0Dh through 0FFh are reserved. If
called they will return with the Carry flag set and AL = 0Fh
(Function not supported).
Programmer's Notes
None
============================================================
Get Version
This service returns the version of DMA services as well as
information about the hardware, size of buffers, and support
of automatic memory remapping.
To Call
AH = 81h
AL = 02h
DX = Flags
All bits reserved and must be zero
Returns
If function was successful:
Carry clear
AH = Major specification version # (binary, currently
1)
AL = Minor specification version # (binary, currently
0)
BX = Product number
CX = Product revision number
SI:DI = Maximum DMA buffer size in bytes that can be
requested.
DX = Flags
Bit 0 = 1 if PC/XT bus architecture (DMA in first
meg only)
Bit 1 = 1 if physical buffer/remap region is in
first meg
Bit 2 = 1 if automatic remap supported
Bit 3 = 1 if all memory physically contiguous
Other flags reserved and must be zero
If function was not successful:
Carry flag set
AL = Error code
10h = Reserved flag bits set in DX
Programmer's Notes
o The version numbers returned in AH and AL are used
to determine the level of functionality supported
by the current implementation. The current driver
will return AX=0100h.
o Bit 3 of the flag word will only be set in
environments that run in protected mode but do not
use paging, such as 286 DOS extenders. In these
environments, the DMA services are only provided
to convert selector:offset linear address pairs
into physical addresses.
============================================================
Lock DMA Region
This service is used to determine if a target DMA region is
in contiguous physical memory. If it is contiguous, then
this service returns the physical address of the region so
that the software can program for the DMA. A locked DMA
region must always be unlocked once the DMA is complete.
If the DMA controller has memory placement restrictions
(i.e. below 1Mb), then it can compare the returned physical
address; if the address is not suitable, then the program
must unlock the region and request a DMA buffer.
Some implementations of the DMA services will attempt to
remap pages to force the region to be contiguous physical
memory. The caller can disable this behavior by setting bit
3 in DX. Normally, it is faster for a device to split
transfers or use a DMA buffer instead of going through the
remap process.
It is often convenient to use the automatic buffer
allocation option of this service. If the DMA region can
not be locked for any reason then the service will attempt
to allocate a DMA buffer. If desired, the data in the
region will be automatically copied into the buffer.
To Call
AH = 81h
AL = 03h
DX = Flags
Bit 1 = 1 if data should be copied into buffer
(ignored if bit 2 = 1)
Bit 2 = 1 if buffer should not be allocated if
region is not contiguous or crosses a
physical alignment boundary specified by bits
4 and 5
Bit 3 = 1 if automatic remap should not be
attempted
Bit 4 = 1 if region must not cross a 64K physical
alignment boundary
Bit 5 = 1 if region must not cross a 128K physical
alignment boundary
All other bits reserved and must be zero
ES:DI = Pointer to DMA Descriptor Structure
The caller must fill in the region size, linear
offset, and selector/segment fields before calling
this service
Returns
If function was successful:
Carry flag clear
Memory is locked
Physical address field of DDS contains the starting
physical address of the region.
The buffer ID field will contain the ID of the
allocated buffer or 0 if no buffer was allocated.
If function was not successful:
Carry flag set
Memory is not locked
Region size field of DDS contains the maximum
contiguous length in bytes.
AL = Error code
01h = Region specified was not contiguous memory
02h = Region crossed a physical alignment boundary
03h = Unable to lock pages (virtual memory systems
only)
05h = Region too large for buffer
06h = Buffer currently in use
07h = Invalid memory region
10h = Reserved flag bits set in DX
Programmer's Notes
o Memory is locked on a page granular basis. A
single page can be locked more than once, thus
allowing two DMA regions to overlap on a single
page. Page locking is maintained as a count.
Some systems need not maintain a count since
memory will never be discarded or moved. In these
systems, Unlock DMA Region will never fail.
o If the automatic buffer allocation option is
selected by clearing bit 2 of the flags in DX,
then a buffer will be automatically allocated if
the region could not be locked. If data should be
copied into the buffer for a memory read operation
then bit 1 of the flags in DX should be set. If
lock is going to fail and bit 2 is clear, but no
buffer is supported, then the actual cause of the
error is reported as the error message, rather
than returning a buffer not available error (4).
o You may want to wait in a loop if this function
returns a "Buffer in use" error to allow another
device time to release the buffer. For more
details refer to the documentation for Request DMA
Buffer on page 14.
o The buffer alignment mask should be used for
devices that have physical memory boundary
constraints. For example, on an AT architecture,
the standard DMA controllers will "wrap" at 64K or
128K physical boundaries. If the DMA controller
being programmed has an alignment constraint, then
the applicable bit in DX should be set.
===========================================================
Unlock DMA Region
Service to unlock a previously locked DMA region.
To Call
AH = 81h
AL = 04h
DX = Flags
Bit 1 = 1 if data should be copied out of buffer
All other bits reserved and must be zero
ES:DI = Pointer to DMA Descriptor Structure
The caller must fill in the region size, physical
address, and buffer ID fields before calling this
service (Usually the caller simply passes the same
structure which was filled in by the call to Lock
DMA Region).
Returns
If function was successful:
Carry flag clear
Memory is unlocked or no count maintained
If function was not successful:
Carry flag set
All memory remains locked
AL = Error code
08h = Memory was not locked
0Ah = Invalid Buffer ID
10h = Reserved flag bits set in DX
Programmer's Notes
o This service releases a DMA buffer, if one was
allocated by the Lock DMA Region call (if Buffer
ID is non-zero in the DDS), so any data in it will
be lost. If the DMA transfer was a memory write
operation, then setting bit 1 in the DX flags
parameter will copy the data out of the buffer
before it is released.
============================================================
Scatter/Gather Lock Region
This service is provided so that hardware devices that
support automatic scatter/gather can determine the actual
physical regions of and lock an entire linear address range
in one call. Device drivers that break up DMA requests may
also want to use this service instead of repeatedly calling
lock DMA region.
To Call
AH = 81h
AL = 05h
DX = Flags
Bit 6 = 1 if EDDS should be returned with page
table entries
Bit 7 = 1 if only present pages should be locked,
not present pages will be identified as a
page table entry of 0 (bit 7 is ignored, if
bit 6 = 0)
All other bits reserved and must be zero
ES:DI = Pointer to one of the following extended DDS:
If option bit 6 = 0 then return Extended DDS (EDDS)
with table of physical regions (address and size
pairs):
DESCRIPTION OFFSET
Region Size in Bytes 00h
Linear Offset 04h
Reserved Segment/Selector 08h
# Used # Avail 0Ch
Region 0 Physical Address 10h
Region 0 Size in Bytes 14h
Region 1 Physical Address 18h
Region 1 Size in Bytes 1Ch
. . . . . .
. . . . . .
Region n Physical Address 10h+n*8
Region n Size in Bytes 14h+n*8
If option bit 6 = 1 then return Extended DDS with table
of page table entries (1 entry per 4Kb page in the
same format as 80386 page table entries):
DESCRIPTION OFFSET
Region Size in Bytes 00h
Linear Offset 04h
Reserved Segment/Selector 08h
# Used # Avail 0Ch
Page table entry 0 10h
Page table entry 1 14h
. . . . . .
. . . . . .
Page table entry n 10h+n*4
Each page table entry contains the physical page number
in the upper 20 bits; the lower 12 bits are flag
bits:
Bit 0 = 1 if the page is present and locked
Bits 1..11 are reserved and will be zero
If option bit 7 = 1, then pages in the region which do
not have a physical page assigned will have a
page table entry of 0, and will not be locked by
this call.
The caller must fill in the region size, linear segment
and offset, and number available field. The #
Avail field specifies the number of physical
regions/page table entries in the data structure.
Returns
If function was successful:
Carry flag is clear
The # used field will contain the number of table
entires filled in with physical regions
information.
If bit 6 of option flags was 1 (page table copy) then
low twelve bits of BX = Offset in first page to
start of region (high 4 bits will be zero).
If function was not successful:
Carry flag is set
Memory is not locked
Region size field of DDS contains the maximum length in
bytes that can be locked and described in the DDS
table.
Table entries are undefined.
AL = Error code
03h = Unable to lock pages
07h = Invalid memory region
09h = Number of physical regions/pages was greater
than table length (The # used field will
contain the number of table entries needed to
describe the DMA region.)
10h = Reserved flag bits set in DX
Programmer's Notes
o The maximum number of physical regions required
can be computed as:
(Linear Address AND 0FFFh) + Region Size + 0FFFh
1000h
============================================================
Scatter/Gather Unlock Region
This service is used to unlock a region that was locked by
the Scatter/Gather Lock Region service.
To Call
AH = 81h
AL = 06h
DX = Flags
Bit 6 = 1 if EDDS contains page table entries
Bit 7 = 1 if EDDS may contain not present pages,
not present pages are identified as a page
table entry of 0 (bit 7 is ignored, if bit 6
= 0)
All other bits reserved and must be zero
ES:DI = Pointer to the extended DDS that was used when
calling the Scatter/Gather Lock Region service.
Returns
If function was successful:
Carry flag is clear
Memory is unlocked
If function was not successful:
Carry flag is set
AL = Error code
08h = Memory was not locked
10h = Reserved flag bits set in DX
Programmer's Notes
o Only the region size, linear offset and
segment/selector fields are used. Therefore, the
physical address/size or page table entries do not
need to be maintained, unless bits 6 and 7 were
set in DX in the call to Scatter/Gather Lock
Region. If this special form of page table lock
was used, then the table is required so that the
correct pages can be unlocked.
============================================================
Request DMA Buffer
Buffered DMA requires a device driver to request a DMA
buffer, copy data into the buffer (if a memory read
operation is required), start the DMA transfer with
programmed I/O, copy data from the buffer (if a memory write
operation is required), and release the DMA buffer. The
data must be copied to/from the DMA buffer before release is
called and the physical address of the buffer must be
considered invalid as soon as release is called.
To Call
AH = 81h
AL = 07h
DX = Flags
Bit 1 = 1 if data should be copied into buffer
All other bits reserved and must be zero
ES:DI = Pointer to DMA Descriptor Structure
The caller must fill in the region size field. If
automatic copy is selected (bit 1 set) then the
caller must also fill in the linear region segment
and region offset fields.
Returns
If function was successful:
Carry flag clear
The physical address field of the DDS contains the
starting physical address of the buffer.
The region size field specifies the size of the buffer.
The buffer ID field contains the ID of the allocated
buffer
If automatic copy was selected then data was copied
into the buffer.
If function was not successful:
Carry flag set
AL = Error code
04h = No buffer available
05h = Region too large for buffer
06h = Buffer currently in use
07h = Invalid memory region
10h = Reserved flag bits set in DX
Programmer's Notes
o Under Windows/386 devices will often want to enter
a Windows/386 critical section to prevent running
other VMs while they are using a DMA buffer.
o If the buffer is in use you may want to spin in a
loop with interrupts enabled and repeatedly
attempt to allocate the buffer to allow another
device time to complete its DMA.
o Your device driver must either spin in a wait loop
until the DMA is complete and then release
ownership of the buffer or it must release
ownership of the buffer from a hardware interrupt.
Releasing ownership from hardware interrupts will
allow other devices to wait for the buffer to be
freed as described above.
============================================================
Release DMA Buffer
Releases a DMA buffer that was previously requested. The
physical address should be considered invalid following this
call.
To Call
AH = 81h
AL = 08h
DX = Flags
Bit 1 = 1 if data should be copied out of buffer
All other bits reserved and must be zero
ES:DI = Pointer to DMA Descriptor Structure
The caller must fill in the buffer ID field of the
DDS before calling this service.
Returns
If function was successful:
Carry flag clear
If function was not successful:
Carry flag set
AL = Error code
0Ah = Invalid buffer ID
10h = Reserved flag bits set in DX
Programmer's Notes
None
============================================================
Copy Into DMA Buffer
Copy data from the user's buffer into the DMA buffer to
prepare for a memory read DMA transfer.
To Call
AH = 81h
AL = 09h
DX = Flags
All bits reserved and must be zero
ES:DI = Pointer to DMA Descriptor Structure
The caller must fill in the buffer ID field, the
fword segment/selector:linear offset fields to
specify the source address for the copy, and the
region size.
BX:CX = Starting offset in DMA buffer to copy
The size field of the DDS determines the number of
bytes that will be copied
Returns
If function was successful:
Carry flag clear
If function was not successful:
Carry flag set
AL = Error code
0Ah = Invalid buffer ID
0Bh = Copy count+offset is greater than buffer
size
10h = Reserved flag bits set in DX
============================================================
Copy Out Of DMA Buffer
Copy data from the DMA buffer into the user's buffer after a
memory write DMA transfer.
To Call
AH = 81h
AL = 0Ah
DX = Flags
All bits reserved and must be zero
ES:DI = Pointer to DMA Descriptor Structure
The caller must fill in the buffer ID field, the
fword segment/selector:linear offset fields to
specify the destination address for the copy, and
the region size.
BX:CX = Starting offset in DMA buffer to copy
The size field of the DDS determines the number of
bytes that will be copied
Returns
If function was successful:
Carry flag clear
If function was not successful:
Carry flag set
AL = Error code
0Ah = Invalid buffer ID
0Bh = Copy count+offset is greater than buffer
size
10h = Reserved flag bits set in DX
============================================================
Disable DMA Translation
Environments that support the DMA services will trap the
standard DMA I/O ports and attempt to remap the client's
addresses, which are assumed to be linear addresses, to the
appropriate physical address. However, programs which use
the DMA services to determine the physical address of their
DMA region must disable the automatic remapping of standard
DMA by calling this function.
A disable count is maintained so you must call Enable DMA
Translation for every call to this service before automatic
DMA translation will be enabled.
To Call
AH = 81h
AL = 0Bh
BX = DMA channel number
DX = Flags
All bits reserved and must be zero
Returns
If function was successful:
Carry flag clear
If function was not successful:
Carry flag set
AL = Error code
0Ch = Invalid DMA channel number
0Dh = Disable count overflow
10h = Reserved flag bits set in DX
Programmer's Notes
None
============================================================
Enable DMA Translation
This service must be called after calling Disable DMA
Translation to re-enable automatic DMA remapping.
A disable count is maintained so you must call this service
for every call to Disable DMA Translation before automatic
DMA translation will be enabled.
To Call
AH = 81h
AL = 0Ch
BX = DMA channel number
DX = Flags
All bits reserved and must be zero
Returns
If function was successful:
Carry flag clear
If disable count decremented to 0, then Zero flag set
If function was not successful:
Carry flag set
AL = Error code
0Ch = Invalid DMA channel number
0Eh = Disable count underflow (was not previously
disabled). Count not changed.
10h = Reserved flag bits set in DX
Programmer's Notes
None
SUMMARY OF ERROR CODES AND OPTION FLAGS
Error codes:
01h = Region not in contiguous memory
02h = Region crossed a physical alignment boundary
03h = Unable to lock pages
04h = No buffer available
05h = Region too large for buffer
06h = Buffer currently in use
07h = Invalid memory region
08h = Region was not locked
09h = Number of physical pages was greater than table
length
0Ah = Invalid buffer ID
0Bh = Copy out of buffer range
0Ch = Invalid DMA channel number
0Dh = Disable count overflow
0Eh = Disable count underflow
0Fh = Function not supported
10h = Reserved flag bits set in DX
Flags:
Bit 1 = Automatically copy to/from buffer
Bit 2 = Disable automatic buffer allocation
Bit 3 = Disable automatic remap feature
Bit 4 = Region must not cross 64K physical alignment
boundary
Bit 5 = Region must not cross 128K physical alignment
boundary
Bit 6 = Copy page table for scatter gather remap