aboutsummaryrefslogtreecommitdiff
path: root/handbook/dma.sgml
blob: e8b7303fa52954e8dd4377427dcbcd10b9bc05a4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
<!-- $Id: dma.sgml,v 1.7 1997-02-22 12:58:24 peter Exp $ -->
<!-- The FreeBSD Documentation Project -->

<!--
<!DOCTYPE linuxdoc PUBLIC "-//FreeBSD//DTD linuxdoc//EN" [

<!ENTITY % authors SYSTEM "authors.sgml">
%authors;

]>
-->
  <sect><heading>DMA: What it is and how it works<label id="dma"></heading>

    <p><em>Copyright &copy; 1995 &a.uhclem;, All Rights Reserved.<newline>
	10 December 1996.</em>

<!-- Version 1(3) -->

      Direct Memory Access (DMA) is a method of allowing data to
      be moved from one location to another in a computer without
      intervention from the central processor (CPU).

      The way that the DMA function is implemented varies between
      computer architectures, so this discussion will limit
      itself to the implementation and workings of the DMA
      subsystem on the IBM Personal Computer (PC), the IBM PC/AT
      and all of its successors and clones.

      The PC DMA subsystem is based on the Intel 8237 DMA
      controller.  The 8237 contains four DMA channels that can
      be programmed independently and any one of the channels may be
      active at any moment.  These channels are numbered 0, 1, 2
      and 3.  Starting with the PC/AT, IBM added a second 8237
      chip, and numbered those channels 4, 5, 6 and 7.

      The original DMA controller (0, 1, 2 and 3) moves one byte
      in each transfer.  The second DMA controller (4, 5, 6, and
      7) moves 16-bits from two adjacent memory locations in each
      transfer, with the first byte always coming from an even-numbered
      address.  The two controllers are identical components and the
      difference in transfer size is caused by the way the second
      controller is wired into the system.

      The 8237 has two electrical signals for each channel, named
      DRQ and -DACK.  There are additional signals with the
      names HRQ (Hold Request), HLDA (Hold Acknowledge), -EOP
      (End of Process), and the bus control signals -MEMR (Memory
      Read), -MEMW (Memory Write), -IOR (I/O Read), and -IOW (I/O
      Write).

      The 8237 DMA is known as a ``fly-by'' DMA controller.  This
      means that the data being moved from one location to
      another does not pass through the DMA chip and is not
      stored in the DMA chip.  Subsequently, the DMA can only
      transfer data between an I/O port and a memory address, but
      not between two I/O ports or two memory locations.

      <quote><em>Note:</em> The 8237 does allow two channels to
	be connected together to allow memory-to-memory DMA
	operations in a non-``fly-by'' mode, but nobody in the PC
	industry uses this scarce resource this way since it is
	faster to move data between memory locations using the
	CPU.</quote>

      In the PC architecture, each DMA channel is normally
      activated only when the hardware that uses that DMA
      requests a transfer by asserting the DRQ line for that
      channel.


    <sect1><heading>A Sample DMA transfer</heading>

      <p>Here is an example of the steps that occur to cause a
	DMA transfer.  In this example, the floppy disk
	controller (FDC) has just read a byte from a diskette and
	wants the DMA to place it in memory at location
	0x00123456.  The process begins by the FDC asserting the
	DRQ2 signal to alert the DMA controller.

	The DMA controller will note that the DRQ2 signal is asserted.
	The DMA controller will then make sure that DMA channel 2
	has been programmed and is enabled.  The DMA controller
	also makes sure that none of the other DMA channels are active
	or have a higher priority.  Once these checks are
	complete, the DMA asks the CPU to release the bus so that
	the DMA may use the bus.  The DMA requests the bus by
	asserting the HRQ signal which goes to the CPU.

	The CPU detects the HRQ signal, and will complete
	executing the current instruction.  Once the processor
	has reached a state where it can release the bus, it
	will.  Now all of the signals normally generated by the
	CPU (-MEMR, -MEMW, -IOR, -IOW and a few others) are
	placed in a tri-stated condition (neither high or low)
	and then the CPU asserts the HLDA signal which tells the
	DMA controller that it is now in charge of the bus.  

	Depending on the processor, the CPU may be able to
	execute a few additional instructions now that it no
	longer has the bus, but the CPU will eventually have to
	wait when it reaches an instruction that must read
	something from memory that is not in the internal
	processor cache or pipeline.

	Now that the DMA ``is in charge'', the DMA activates its
	-MEMR, -MEMW, -IOR, -IOW output signals, and the address
	outputs from the DMA are set to 0x3456, which will be
	used to direct the byte that is about to transferred to a
	specific memory location.

	The DMA will then let the device that requested the DMA
	transfer know that the transfer is commencing.  This is
	done by asserting the -DACK signal, or in the case of the
	floppy disk controller, -DACK2 is asserted.

	The floppy disk controller is now responsible for placing
	the byte to be transferred on the bus Data lines.  Unless
	the floppy controller needs more time to get the data
	byte on the bus (and if the peripheral does need more time it
	alerts the DMA via the READY signal), the DMA will wait
	one DMA clock, and then de-assert the -MEMW and -IOR
	signals so that the memory will latch and store the byte
	that was on the bus, and the FDC will know that the byte
	has been transferred.

	Since the DMA cycle only transfers a single byte at a
	time, the FDC now drops the DRQ2 signal, so that the DMA
	knows it is no longer needed.  The DMA will de-assert the
	-DACK2 signal, so that the FDC knows it must stop placing
	data on the bus.

	The DMA will now check to see if any of the other DMA
	channels have any work to do.  If none of the channels
	have their DRQ lines asserted, the DMA controller has
	completed its work and will now tri-state the -MEMR,
	-MEMW, -IOR, -IOW and address signals.

	Finally, the DMA will de-assert the HRQ signal.  The CPU
	sees this, and de-asserts the HOLDA signal.  Now the CPU
	activates its -MEMR, -MEMW, -IOR, -IOW and address lines,
	and it resumes executing instructions and accessing main
	memory and the peripherals.

	For a typical floppy disk sector, the above process is
	repeated 512 times, once for each byte.  Each time a byte
	is transferred, the address register in the DMA is
	incremented and the counter that shows how many bytes are
	to be transferred is decremented.

	When the counter reaches zero, the DMA asserts the EOP
	signal, which indicates that the counter has reached zero
	and no more data will be transferred until the DMA
	controller is reprogrammed by the CPU.  This event is
	also called the Terminal Count (TC).  There is only one
	EOP signal, because only one DMA channel can be active at
	any instant.

	If a peripheral wants to generate an interrupt when the
	transfer of a buffer is complete, it can test for its
	-DACK signal and the EOP signal both being asserted at
	the same time.  When that happens, it means the DMA will not
	transfer any more information for that peripheral without
	intervention by the CPU.  The peripheral can then assert
	one of the interrupt signals to get the processors'
	attention.  The DMA chip itself is not capable of
	generating an interrupt.  The peripheral and its
	associated hardware is responsible for generating any
	interrupt that occurs.

	It is important to understand that although the CPU
	always releases the bus to the DMA when the DMA makes the
	request, this action is invisible to both applications
	and the operating systems, except for slight changes in
	the amount of time the processor takes to execute
	instructions when the DMA is active.  Subsequently, the
	processor must poll the peripheral, poll the registers in
	the DMA chip, or receive an interrupt from the peripheral
	to know for certain when a DMA transfer has completed.


<sect1><heading>DMA Page Registers and 16Meg address space limitations</heading>

      <p>You may have noticed earlier that instead of the DMA
	setting the address lines to 0x00123456 as we said
	earlier, the DMA only set 0x3456.  The reason for this
	takes a bit of explaining.

	When the original IBM PC was designed, IBM elected to use
	both DMA and interrupt controller chips that were
	designed for use with the 8085, an 8-bit processor with
	an address space of 16 bits (64K).  Since the IBM PC
	supported more than 64K of memory, something had to be
	done to allow the DMA to read or write memory locations
	above the 64K mark.  What IBM did to solve this problem
	was to add a latch for each DMA channel that holds the
	upper bits of the address to be read to or written from.
	Whenever a DMA channel is active, the contents of that
	latch are written to the address bus and kept there until
	the DMA operation for the channel ends.  These latches
	are called ``Page Registers''.

	So for our example above, the DMA would put the 0x3456
	part of the address on the bus, and the Page Register for
	DMA channel 2 would put 0x0012xxxx on the bus.  Together,
	these two values form the complete address in memory that
	is to be accessed.

	Because the Page Register latch is independent of the DMA
	chip, the area of memory to be read or written must not
	span a 64K physical boundary.  If the DMA accesses memory
	location 0xffff, after the transfer the DMA will then increment
	the address register and the DMA will access the next byte at
	location 0x0000, not 0x10000.  The results of letting this
	happen are probably not intended.

	<quote><em>Note:</em> ``Physical'' 64K boundaries should
	  not be confused with 8086-mode 64K ``Segments'', which
	  are created by adding a segment register with an offset
	  register.  Page Registers have no address overlap.</quote>

	To further complicate matters, the external DMA address
	latches on the PC/AT hold only eight bits, so that gives
	us 8+16=24 bits, which means that the DMA can only point
	at memory locations between 0 and 16Meg.  For newer
	computers that allow more than 16Meg of memory, the
	PC-compatible DMA cannot access memory locations above 16Meg.

	To get around this restriction, operating systems will
	reserve a buffer in an area below 16Meg that also does not
	span a physical 64K boundary.  Then the DMA will be
	programmed to transfer data from the peripheral and into that
	buffer.  Once the DMA has moved the data into this buffer,
	the operating system will then copy the data from the buffer
	to the address where the data is really supposed to be stored.

	When writing data from an address above 16Meg to a
	DMA-based peripheral, the data must be first copied from
	where it resides into a buffer located below 16Meg, and
	then the DMA can copy the data from the buffer to the
	hardware.  In FreeBSD, these reserved buffers are called
	``Bounce Buffers''.  In the MS-DOS world, they are
	sometimes called ``Smart Buffers''.


    <sect1><heading>DMA Operational Modes and Settings</heading>

      <p>The 8237 DMA can be operated in several modes.  The main
	ones are:

<descrip>

	  <tag/Single/ A single byte (or word) is transferred.
	    The DMA must release and re-acquire the bus for each
	    additional byte.  This is commonly-used by devices
	    that cannot transfer the entire block of data
	    immediately.  The peripheral will request the DMA
	    each time it is ready for another transfer.

	    The floppy disk controller only has a one-byte
	    buffer, so it uses this mode.


	  <tag>Block/Demand</tag> Once the DMA acquires the
	    system bus, an entire block of data is transferred,
	    up to a maximum of 64K.  If the peripheral needs
	    additional time, it can assert the READY signal to
	    suspend the transfer briefly.  READY should not be
	    used excessively, and for slow peripheral transfers,
	    the Single Transfer Mode should be used instead.

	    The difference between Block and Demand is that once a
	    Block transfer is started, it runs until the transfer
	    count reaches zero.  DRQ only needs to be asserted
	    until -DACK is asserted.  Demand Mode will transfer
	    one more bytes until DRQ is de-asserted and the DMA
	    pauses the transfer and releases the bus back to the CPU.
	    When DRQ is asserted later, the transfer resumes where
	    it was suspended.

	    Older hard disk controllers used Demand Mode until
	    CPU speeds increased to the point that it was more
	    efficient to transfer the data using the CPU, particularly
	    if the memory locations used in the transfer were above the
	    16Meg mark.
		

	  <tag>Cascade</tag> This mechanism allows a DMA channel
	    to request the bus, but then the attached peripheral
	    device is responsible for placing the addressing
	    information on the bus instead of the DMA.  This is also
	    known as ``Bus Mastering''.

	    When a DMA channel in Cascade Mode receives control
	    of the bus, the DMA does not place addresses and I/O
	    control signals on the bus like the DMA normally does
	    when it is active.  Instead, the DMA only asserts the
	    -DACK signal for this channel.

	    At this point it is up to the device connected to that DMA
	    channel to provide address and bus control signals.
	    The peripheral has complete control over the system
	    bus, and can do reads and/or writes to any address
	    below 16Meg.  When the peripheral is finished with
	    the bus, it de-asserts the DRQ line, and the DMA
	    controller can return control to the CPU or to some
	    other DMA channel.

	    Cascade Mode can be used to chain multiple DMA
	    controllers together, and this is exactly what DMA
	    Channel 4 is used for in the PC.  When a peripheral
	    requests the bus on DMA channels 0, 1, 2 or 3, the
	    slave DMA controller asserts HLDREQ, but this wire is
	    actually connected to DRQ4 on the primary DMA
	    controller.  The primary DMA controller then requests
	    the bus from the CPU using HLDREQ.  Once the bus is
	    granted, -DACK4 is asserted, and that wire is
	    actually connected to the HLDA signal on the slave
	    DMA controller.  The slave DMA controller then
	    transfers data for the DMA channel that requested it,
	    or the slave DMA may grant the bus to a peripheral
	    that wants to perform its own bus-mastering, such as
	    a SCSI controller.

	    Because of this wiring arrangement, only DMA channels
	    0, 1, 2, 3, 5, 6 and 7 are usable on PC/AT systems.

	    <quote><em>Note:</em> DMA channel 0 was reserved for
	      refresh operations in early IBM PC computers, but
	      is generally available for use by peripherals in
	      modern systems.</quote>

	    When a peripheral is performing Bus Mastering, it is
	    important that the peripheral transmit data to or
	    from memory constantly while it holds the system bus.
	    If the peripheral cannot do this, it must release the
	    bus frequently so that the system can perform refresh
	    operations on main memory.

	    The Dynamic RAM used in all PCs for main memory must be
	    accessed frequently to keep the bits stored in the
	    components "charged".  Dynamic RAM essentially consists
	    of millions of capacitors with each one holding one bit
	    of data.  These capacitors are charged with power to
	    represent a "1" or drained to represent a "0".  Because
	    all capacitors leak, power must be added at regular intervals
	    to keep the "1" values intact.  The RAM chips actually handle
	    the task of pumping power back into all of the appropriate
	    locations in RAM, but they must be told when to do it by
	    the rest of the computer so that the refresh activity won't
	    interfere with the computer wanting to access RAM normally.
	    If the computer is unable to refresh memory, the contents
	    of memory will become corrupted in just a few milliseconds.  

	    Since memory read and write cycles ``count'' as refresh
	    cycles (a dynamic RAM refresh cycle is actually an incomplete
	    memory read cycle), as long as the peripheral
	    controller continues reading or writing data to
	    sequential memory locations, that action will refresh
	    all of memory.
	
	    Bus-mastering is found in some SCSI host interfaces and
	    other high-performance peripheral controllers.


	  <tag>Autoinitialize</tag> This mode causes the DMA to
	    perform Byte, Block or Demand transfers, but when the
	    DMA transfer counter reaches zero, the counter and
	    address are set back to where they were when the DMA
	    channel was originally programmed.  This means that
	    as long as the peripheral requests transfers, they will
	    be granted.  It is up to the CPU to move new data
	    into the fixed buffer ahead of where the DMA is about
	    to transfer it when doing output operations, and read new
	    data out of the buffer behind where the DMA is writing
	    when doing input operations.

	    This technique is frequently used on audio devices that
	    have small or no hardware ``sample'' buffers.  There is
	    additional CPU overhead to manage this ``circular'' buffer,
	    but in some cases this may be the only way to eliminate the
	    latency that occurs when the DMA counter reaches zero
	    and the DMA stops transfers until it is reprogrammed.
	</descrip>

    <sect1><heading>Programming the DMA</heading>

      <p>The DMA channel that is to be programmed should always
	be ``masked'' before loading any settings.  This is because
	the hardware might unexpectedly assert DRQ, and the DMA might
	respond, even though not all of the parameters have been
	loaded or updated.

	Once masked, the host must specify the direction of the
	transfer (memory-to-I/O or I/O-to-memory), what mode of
	DMA operation is to be used for the transfer (Single,
	Block, Demand, Cascade, etc), and finally the address and
	length of the transfer are loaded.  The length that is
	loaded is one less than the amount you expect the DMA to
	transfer.  The LSB and MSB of the address and length are
	written to the same 8-bit I/O port, so another port must
	be written to first to guarantee that the DMA accepts the
	first byte as the LSB and the second byte as the MSB of
	the length and address.

	Then, be sure to update the Page Register, which is
	external to the DMA and is accessed through a different
	set of I/O ports.

	Once all the settings are ready, the DMA channel can be
	un-masked.  That DMA channel is now considered to be
	``armed'', and will respond when DRQ is asserted.

	Refer to a hardware data book for precise programming
	details for the 8237.  You will also need to refer to the
	I/O port map for the PC system, which describes where
	the DMA and Page Register ports are located.  A complete
	table is located below.


    <sect1><heading>DMA Port Map</heading>

      <p>All systems based on the IBM-PC and PC/AT have the DMA
	hardware located at the same I/O ports.  The complete
	list is provided below.  Ports assigned to DMA Controller
	&num;2 are undefined on non-AT designs.

<sect2><heading>0x00 - 0x1f DMA Controller &num;1 (Channels 0, 1, 2 and 3)</heading>

<p>DMA Address and Count Registers

<verb>
0x00	write	Channel 0 starting address
0x00	read	Channel 0 current address
0x02	write	Channel 0 starting word count
0x02	read	Channel 0 remaining word count

0x04	write	Channel 1 starting address
0x04	read	Channel 1 current address
0x06	write	Channel 1 starting word count
0x06	read	Channel 1 remaining word count

0x08	write	Channel 2 starting address
0x08	read	Channel 2 current address
0x0a	write	Channel 2 starting word count
0x0a	read	Channel 2 remaining word count

0x0c	write	Channel 3 starting address
0x0c	read	Channel 3 current address
0x0e	write	Channel 3 starting word count
0x0e	read	Channel 3 remaining word count
</verb>

DMA Command Registers

<verb>
0x10	write	Command Register
0x10	read	Status Register
0x12	write	Request Register
0x12	read	-
0x14	write	Single Mask Register Bit
0x14	read	-
0x16	write	Mode Register
0x16	read	-
0x18	write	Clear LSB/MSB Flip-Flop
0x18	read	-
0x1a	write	Master Clear/Reset
0x1a	read	Temporary Register
0x1c	write	Clear Mask Register
0x1c	read	-
0x1e	write	Write All Mask Register Bits
0x1e	read	-
</verb>

<sect2><heading>0xc0 - 0xdf DMA Controller &num;2 (Channels 4, 5, 6 and 7)</heading>

<p>DMA Address and Count Registers

<verb>
0xc0	write	Channel 4 starting address
0xc0	read	Channel 4 current address
0xc2	write	Channel 4 starting word count
0xc2	read	Channel 4 remaining word count

0xc4	write	Channel 5 starting address
0xc4	read	Channel 5 current address
0xc6	write	Channel 5 starting word count
0xc6	read	Channel 5 remaining word count

0xc8	write	Channel 6 starting address
0xc8	read	Channel 6 current address
0xca	write	Channel 6 starting word count
0xca	read	Channel 6 remaining word count

0xcc	write	Channel 7 starting address
0xcc	read	Channel 7 current address
0xce	write	Channel 7 starting word count
0xce	read	Channel 7 remaining word count
</verb>

DMA Command Registers

<verb>
0xd0	write	Command Register
0xd0	read	Status Register
0xd2	write	Request Register
0xd2	read	-
0xd4	write	Single Mask Register Bit
0xd4	read	-
0xd6	write	Mode Register
0xd6	read	-
0xd8	write	Clear LSB/MSB Flip-Flop
0xd8	read	-
0xda	write	Master Clear/Reset
0xda	read	Temporary Register
0xdc	write	Clear Mask Register
0xdc	read	-
0xde	write	Write All Mask Register Bits
0xde	read	-
</verb>

<sect2><heading>0x80 - 0x9f DMA Page Registers</heading>

<p><verb>
0x87	r/w	DMA Channel 0
0x83	r/w	DMA Channel 1
0x81	r/w	DMA Channel 2
0x82	r/w	DMA Channel 3

0x8b	r/w	DMA Channel 5
0x89	r/w	DMA Channel 6
0x8a	r/w	DMA Channel 7

0x8f		Refresh
</verb>