DMA
DMA: Was es ist und wie es arbeitet
Copyright © 1995,1997 &a.uhclem;, Alle Rechte vorbehalten.
10. Dezember 1996. Letztes Update Oktober 1997.
Direct Memory Access (DMA) ist eine Methode, die es erlaubt, Daten von
einer Stelle in einem Rechnern an eine andere zu transferieren ohne
Eingreifen des Prozessors (CPU).
Die Art und Weise, in der die DMA-Funktion implementiert ist, variiert
zwischen den Rechnerarchitekturen. Daher beschränken wir uns im Folgenden
ausschliesslich auf die Methoden und Implementierungen auf IBM
Personal Computer (PC), dem IBM PC/AT und all seinen Nachfolgern und
Nachbauten.
Das DMA-Subsystem basiert auf dem &intel; 8237 DMA-Controller. Der
8237 enthält vier DMA-Kanäle, welche unabhängig voneinander programmiert
werden können und jeder dieser Kanäle kann zu einem beliebigen Zeitpunkt
aktiv sein. Diese Kanäle sind mit 0, 1, 2 und 3 nummeriert. Beginnend
mit dem PC/AT fügte IBM einen zweiten 8237-Chip hinzu und nummerierte
dessen Kanäle mit 4, 5, 6 und 7.
Der originale DMA-Controller (0, 1, 2 and 3) bewegt ein Byte bei jedem
Transfer. Der zweite DMA-Controller (4, 5, 6, and 7) bewegt 16-Bits aus
zwei benachbarten Speicherbereichen bei jedem Transfer, wobei das erste Byte
immer von einer geradzahligen Adresse stammt. Die zwei Controller sind
identische Komponenten und der Unterschied in der Transfergröße wird durch
die Art und Weise verursacht, wie der zweite Controller im System
beschaltet ist.
Der 8237 hat zwei elektrische Signale für jeden Kanal: DRQ und
-DACK. Zusätzlich gibt es weitere Signale mit den Namen HRQ (Hold Request),
HLDA (Hold Acknowledge), -EOP (End of Process) sowie die Kontrollsignale
für den Bus: -MEMR (Memory Read), -MEMW (Memory Write), -IOR (I/O Read)
und -IOW (I/O Write).
Der 8237 DMA-Controller ist bekannt als ein fly-by
-DMA-Controller.
Das bedeutet, daß die von einem zu einem anderen Bereich bewegten Daten
weder den DMA-Chip durchlaufen noch darin gespeichert werden. Daraus
folgernd kann der DMA-Controller nur zwischen einem I/O-Port und einer Speicheradresse
Daten bewegen, nicht zwischen zwei I/O-Ports oder zwei Speicherbereichen.
Der 8237 erlaubt es, daß zwei Kanäle verbunden sind, um einen
höheren Durchsatz bei DMA-Operationen zwischen verschiedenen Speicherbereichen
in einem nicht-fly-by
-Modus zu gewährleisten. Aber niemand
in der PC-Industrie benutzt diese begrenzte Resource, da es schneller ist
die Daten mittels der CPU zwischen Speicherbereichen zu bewegen.
In der PC-Architekur wird jeder DMA-Kanal normalerweise nur dann
aktiviert, wenn die Hardware, welche einen gegebenen DMA-Kanal benutzt,
einen Transfer durch Setzen der DRQ-Linie verlangt.
Beispiel eines DMA-Transfers
Hier ist ein Beispiel für die notwendigen Schritte, welche einen
DMA-Transfer veranlassen und durchführen. In diesem Beispiel hat der
Diskettencontroller (floppy disk controller, FDC) nur ein Byte zu lesen
und verlangt vom DMA-Controller dieses Byte im Speicher an der Adresse
0x00123456 abzulegen. Der Prozess beginnt damit, daß der FDC das
DRQ2-Signal (die DRQ-Linie für DMA-Kanal 2) einfügt, um den DMA-Controller
zu alarmieren.
Der DMA-Controller nimmt wahr, daß das DRQ2-Signal eingefügt ist.
Der DMA-Controller stellt sicher, daß der DMA-Kanal 2 programmiert und
unmaskiert (freigegeben) ist. Der DMA-Controller stellt gleichzeitig sicher,
daß keiner der anderen DMA-Kanäle aktiv ist oder aktiv sein möchte
mit einer höheren Priorität. Sobald all diese Überprüfungen durchlaufen
sind, fordert der DMA-Controller die CPU auf, den Bus freizugeben, damit
der DMA-Controller ihn nutzen kann. Diese Anforderung erfolgt mittels des
HRQ-Signals, welches zur CPU geht.
Die CPU erkennt das HRQ-Signal und führt die momentane Instruktion
komplett aus. Sobald die CPU den Bus freigeben kann, wird er dies tun.
Nun sind alle normalerweise von der CPU erzeugten Signale (-MEMR, -MEMW,
-IOR, -IOW und ein paar andere) in einer Situation mit drei Zuständen
(entweder hoch oder niedrig) und die CPU teilt dem DMA-Controller mittels
des HLDA-Signals mit, daß er nun die Kontrolle über den Bus hat.
Abhängig vom Prozessor kann die CPU noch einige zusätzliche Instruktionen
ausführen ohne die Kontrolle des Bus, aber sie muß unter Umständen warten,
wenn sie Instruktionen abarbeiten will, welche etwas aus dem Speicher lesen
müssen, was nicht im internen Prozessor-Cache oder der Pipeline ist.
Da der DMA-Controller nun verantwortlich ist
, aktiviert er
-MEMR, -MEMW, -IOR, -IOW Output-Signale und der Output des DMA-Controllers
wird auf 0x3456 gesetzt, damit das zu transferierende Byte zu einem
bestimmten Speicherbereich gelangt.
Der DMA-Controller verständigt nun das Gerät, welches die Anforderung
veranlasst hat, daß der Transfer beginnt. Dies geschieht mittels einfügen
des Signals -DACK signal oder wie hier in unserem Beispiel mittels -DACK2.
Der Floppy-Controller ist nun verantwortlich für das Setzen des
Bytes für den Transport auf den Datenlinien des Bus. Sofern der Floppy-Controller
nicht mehr Zeit braucht, um das Daten-Byte auf den Bus zu bringen
(falls dies erforderlich ist benachrichtigt das Peripheriegerät mittels
READY-Signal den DMA-Controller), dann wird der DMA-Controller ein
Zeitsignal warten und die Signale -MEMW und -IOR widerrufen, damit der
Speicher das Byte auf dem Bus sperrt und speichert und der FDC weiß,
daß das Byte übertragen wurde.
Da der DMA-Zyklus nur ein einzelnes Byte zugleich transferiert,
wird der FDC nun das Signal DRQ2 absetzen und der DMA-Controller weiß,
daß es nicht länger benötigt wird. Der DMA-Controller fügt das -DACK2
-Signal wieder ein und der FDC registriert, daß er aufhören muß Daten an
den Bus zu senden.
Der DMA-Controller wird nun überprüfen, ob andere DMA-Kanäle
irgendwelche Arbeiten bereithalten. Falls keiner der Kanäle DRQ-Linien
eingefügt hat, weiß der Controller, daß er seine Arbeit beendet hat
und versieht -MEMR, -MEMW, -IOR, -IOW und die Adress-Signale mit
drei Zuständen.
Abschliessend setzt der DMA-Controller wieder das HRQ-Signal.
Die CPU registriert dies und setzt wieder das HOLDA-Signal. Die CPU
aktiviert nun ihre -MEMR, -MEMW, -IOR, -IOW und Adress-Linien und
fährt mit der Abarbeitung von Instruktionen und dem Zugriff auf
Hauptspeicher und Peripherie fort.
Für einen typischen Sektor einer Diskette wird der obige Prozess
512 Mal wiederholt, jeweils pro Byte. Nach dem Transfer eines Byte
wird jeweils der Zähler im DMA-Controller vermindert, welcher anzeigt,
wieviel Bytes noch zu übertragen sind.
Sobald der Zähler Null erreicht hat, fügt der DMA-Controller das
EOP-Signal ein, welches anzeigt, daß der Zähler Null erreicht hat
und keine weiteren Daten zu übertragen sind, bis der DMA-Controller
wieder durch die CPU programmiert wird. Dieses Ereignis bezeichnet man
als Terminal Count (TC). Es gibt nur ein EOP-Signal und da nur jeweils
ein DMA-Kanal gleichzeitig aktiv sein kann, muß der aktive DMA-Kanal
auch derjenige sein, welcher soeben seine Aufgabe beendet hat.
Falls ein Peripheriegerät einen Interrupt erzeugen will, wenn der
Transfer eines Pufferspeichers beendet ist, dann kann es überprüfen,
ob sein -DACK-Signal und EOP-Signal gleichzeitig anliegen. Falls dies
zutrifft wird der DMA-Controller keine weiteren Informationen ohne
Eingriff der CPU für dieses Peripheriegerät übertragen. Das Peripheriegerät
kann nun eines der Interrupt-Signale einfügen, um die Aufmerksamkeit der
CPU zu erlangen. In der PC-Architektur ist der DMA-Controller selbst nicht
in der Lage Interrupts zu erzeugen. Das Peripheriegerät und seine
beigeordnete Hardware sind für die Erzeugung jedes Interrupts verantwortlich,
welcher auftritt. In der Folge gibt es Peripheriegeräte, welche
DMA nutzen aber keine Interrupts.
Es ist wichtig zu verstehen, daß obwohl die CPU jedesmal den Bus
an den DMA-Controller freigibt, wenn dieser ihn anfordert, dieser Vorgang
sowohl für das Betriebssystem als auch die Applikation unsichtbar ist
ausser kleinen Änderungen im Zeitbedarf, die der Prozessor benötigt, um
Instruktionen auszuführen, wenn der DMA-Controller aktiv ist. Folglich
muß der Prozessor die Peripheriegeräte und die Register im DMA-Chip
ständig abfragen oder einen Interrupt von einem Peripheriegerät
empfangen, um sicher zu sein, daß ein bestimmter DMA-Transfer
beendet wurde.
DMA-Seitenregister und 16 Megabyte-Adressraumbeschränkungen
Sie haben vielleicht vorhin bemerkt, daß der DMA-Controller die
Adress-Linien nicht auf 0x00123456 gesetzt hat, wie wir angaben, sondern
auf 0x3456. Der Grund hierfür erfordert ein wenig Erklärung.
Als der originale IBM PC entworfen wurde hat IBM entschieden sowohl
DMA als auch Interrupt-Controller einzusetzen, welche für den 8085
entwickelt worden waren, einem 8 Bit-Prozessor mit einem Adressraum
von 16 Bit (64K). Da der IBM PC mehr als 64K unterstützte mußte etwas
geschehen, damit der DMA-Controller Adressbereiche oberhalb der 64K
-Grenze auslesen und beschreiben konnte. IBM führte einen zusätzlichen,
externen Signalspeicher für jeden DMA-Kanal ein, welcher die oberen Bits
einer Adresse enthält, welche ausgelesen oder beschrieben werden muß.
Immer wenn ein DMA-Controller aktiv ist, wird der Inhalt dieses
Signalspeichers zum Adress-Bus hinzugeschrieben und dort festgehalten,
bis die DMA-Operation für diesen Kanal beendet ist. IBM nannte diese
zusätzlichen Signalspeicher Seitenregister
(Page Register).
Für das obige Beispiel würde der DMA-Controller den 0x3456-Teil
der Adresse auf den Bus setzen und das Seitenregister für den
DMA-Kanal 2 würde 0x0012xxxx dem Bus hinzufügen. Zusammen formen
beide Werte die komplette Speicheradresse, auf die zugegriffen
werden soll.
Da das Seitenregister unabhängig vom DMA-Chip ist, weist der
zu lesende oder zu beschreibende Speicherbereich keine auf 64K
limitierte Größe auf. Wenn der DMA-Controller beispielsweise
auf die Speicheradresse 0xffff zugreift, dann wird der Controller
nach dem Transfer das Adress-Register erhöhen und auf das nächste Byte
an der Adresse 0x0000, nicht 0x10000, zugreifen. Dieses Zuzulassen
ist sicher nicht beabsichtigt.
Physikalische
64K-Grenzen sollten nicht mit
8086-Modus 64K-Segmenten
verwechselt werden, welche
erzeugt werden durch mathematisches Hinzufügen eines Segment-Registers
an ein Offset-Register. Seitenregister haben keinen Adressüberhang
und werden durch ein mathematisches OR zusammengefügt.
Um die Angelegenheit noch komplizierter zu machen weisen die externen
DMA Signalspeicher auf dem PC/AT nur 8 Bytes auf, also 8+16 = 24 Bits.
Dies bedeutet, daß der DMA-COntroller nur auf Speicherbereiche innerhalb
von 16 Megabyte zeigen kann. Für neuere Rechner, die mehr als 16 Megabyte
an Speicher aufweisen, kann der Standard PC-kompatible DMA-Controller
keine Speicherbereiche oberhalb von 16 Megabyte adressieren.
Um diese Beschränkung zu umgehen reservieren Betriebssysteme
einen RAM-Puffer in einem Bereich unterhalb von 16 Megabyte, der ebenfalls
nicht einen physisch begrenzten Bereich von 64K umfasst. Dann wird der
DMA-Controller so programmiert, daß er Daten vom Peripheriegerät in
diesen Puffer überträgt. Sobald der DMA-Controller die Daten in den
Puffer übertragen hat, wird das Betriebssystem sie in einen Bereich
kopieren, wo sie endgültig gelagert werden.
Beim Schreiben von Daten von Adressen oberhalb von 16 Megabyte
an ein DMA-basiertes Peripheriegerät müssen die Daten zuerst von dort,
wo sie liegen, in einen Puffer unterhalb von 16 Megabyte geschrieben
werden und dann kann der DMA-Controller die Daten vom Puffer auf die
Peripherie kopieren. In FreeBSD werden diese reservierten Puffer
Bounce Buffers
genannt. In der &ms-dos;-Welt werden sie
manchmal als Smart Buffers
bezeichnet.
Eine neuere Ausführung des 8237, 82374 genannt, weist 16
Bit-Seitenregister auf und erlaubt Zugriff auf den gesamten
32 Bit-Adressraum ohne Zuhilfenahme von Bounce Buffers.
DMA-Operationsmodi und Einstellungen
Der 8237 DMA-Controller kann in verschiedenen Modi betrieben werden.
Die Wichtigsten sind:
Single
Ein einziges Byte (oder Word) wird übertragen. Der DMA-Controller
muß für jedes zusätzliche Byte den Bus freigeben bzw. neu besetzen.
Dieser Modi wird normalerweise von Geräten benutzt, welche nicht
einen gesammten Block von Daten auf einmal transferieren können.
Das Peripheriegerät wird den DMA-Controller jedesmal anfordern,
wenn es für einen weiteren Transfer bereit ist.
Der Standard PC-kompatible Floppy-Controller (NEC 765)
hat nur einen Buffer mit einem Byte, daher nutzt er diesen Modus.
Block/Demand
Sobald der DMA-Controller den Bus übernommen hat wird ein ganzer
Block von Daten übertragen bis zu einem Maximum von 64K. Wenn das
Peripheriegerät zusätzliche Zeit benötigt, kann es das READY-Signal
setzen, um den Transfer kurzfristig zu unterbrechen. READY sollte
nicht exzessiv benutzt werden und für langsame Peripheriegeräte
sollte der Single Transfer-Modus stattdessen genutzt werden.
Der Unterschied zwischen Block und Demand ist, daß sobald ein
Block-Transfer gestartet ist, dieser solange läuft, bis der
Transfer-Zähler Null erreicht. DRQ muß nur gesetzt werden,
bis -DACK geschrieben wird. Der Demand-Modus überträgt ein Byte mehr
bis DRQ wiedereingesetzt wird. An diesem Punkt unterbricht der DMA
-Controller die Übertragung und gibt den Bus wieder der CPU frei.
Wenn DRQ wieder eingesetzt wird geht der Transfer an der Stelle
weiter, an welcher er unterbrochen wurde.
Ältere Festplattencontroller benutzten den Demand-Modus bis
die CPU-Geschwindigkeiten an einen Punkt wuchsen, ab dem der
Transfer mittels CPU schneller war, insbesondere wenn die benutzten
Speicherbereiche jenseits der 16 Megabyte-Marke lagen.
Cascade
Dieser Mechanismus erlaubt einem DMA-Kanal den Bus anzufordern,
wobei dann aber das zugehörige Peripheriegerät dafür verantwortlich
ist die Adressinformationen an den Bus zu senden anstatt des
DMA-Controllers. Dies wird auch dazu genutzt, um eine Technik
einzuführen, die man als Bus Mastering
bezeichnet.
Wenn ein DMA-Kanal im Cascade-Modus Kontrolle über den Bus
erlangt, dann stellt der Controller nicht die Adressen und I/O
-Kontrollsignale auf den Bus, wie es normalerweise der Fall ist.
Stattdessen setzt der Controller nur das -DACK-Signal für den
aktiven DMA-Kanal.
Nun ist es Aufgabe des diesem DMA-Kanal zugehörigen Peripheriegerätes
die Adressen und Bus-Kontrollsignale zu liefern. Das Peripheriegerät
hat vollständige Kontrolle über den Bus und kann Lese- oder
Schreibvorgänge an jeder Adresse unterhalb von 16 Megabyte ausführen.
Wenn das Peripheriegerät fertig ist, setzt es die DRQ-Linie und der
DMA-Controller kann die Kontrolle an die CPU oder einen anderen
DMA-Kanal übergeben.
Der Cascade-Modus kann verwendet werden, um mehrere DMA-Controller
in Reihe zu schalten und genau dafür wird der DMA-Kanal 4 in der
PC-Architektur genutzt. Wenn ein Peripheriegerät den Bus auf den
DMA-Kanälen 0, 1, 2 oder 3 verlangt, dann setzt der abhängige
DMA-Controller (slave DMA) HLDREQ, aber dieser Kanal ist in
Wirklichkeit verbunden mit DRQ4 auf dem primären DMA-Controller
statt mit der CPU. Der primäre DMA-Controller nimmt an, er habe
Arbeit zu leisten auf Kanal 4, und fordert den Bus an von der CPU
mit dem HLDREQ-Signal. Soabld die CPU die Kontrolle des Bus an den
primären DMA-Controller übergeben hat, wird -DACK4 gesetzt und
dieser Kanal ist in Wirklichkeit verbunden mit dem abhängigen
DMA-Controller über das HDLA-Signal. Der abhängige Controller
überträgt dann die Daten für den DMA-Kanal, der die Anforderung
gestellt hat (0, 1, 2 oder 3) oder der Controller übergibt
den Bus an ein Peripheriegerät, welches selbst ein eigenes
Bus-Mastering durchführen will, wie z.B. ein SCSI-Controller.
Wegen dieser Schaltungsanordnung können nur die DMA-Kanäle 0, 1,
2, 3, 5, 6 und 7 mit Peripheriegeräten auf PC/AT-Systemen genutzt
werden.
Der DMA-Kanal 0 war reserviert für Auffrischungs-Operationen
auf frühen IBM PC-Rechnern, aber er ist allgemein verfügbar für
Peripheriegeräte auf modernen Rechnern.
Wenn ein Peripheriegerät Bus Mastering durchführt ist es wichtig,
daß es konstant Daten vom oder zum Speicher überträgt, solange es
die Kontrolle über den Bus hält. Falls das Peripheriegerät dies nicht
kann muß es den Bus häufig freigeben, damit das System
Auffrischungsoperationen am Hauptspeicher vornehmen kann.
Das dynamische RAM als Hauptspeicher in allen PCs muß
regelmässig aufgefrischt werden, damit die gespeicherten Bits
geladen
gehalten werden. Dynamisches Ram besteht
aus Millionen Transistoren, die jedes ein Bit Daten enthalten.
Die Transistoren sind geladen, um 1 darzustellen,
oder entladen, um 0 zu repräsentieren.
Da alle Transistoren Ladung abgeben, muß in regelmässigen Abständen
der Ladungsinhalt aufgefrischt werden durch Wiederbeschreibung,
um den Wert 1 zu erhalten. Die RAM-Chips
übernehmen diese Aufgabe selbst, aber sie müssen angewiesen
werden dazu vom Rest des Rechners, weil die Auffrischungsaktionen
nicht mit dem Zugriff auf das RAM kollidieren dürfen. Falls der
Rechner das RAM nicht auffrischen kann wird der Inhalt des
Speichers binnen weniger Millisekunden beschädigt.
Da Lese- und Schreibzyklen als Auffrischungszyklen
zählen
(ein Auffrischungszyklus eines dynamischen
Ram ist in Wirklichkeit ein unvollständiger Lesezyklus),
wird diese Aktion den gesamten Speicher auffrischen, solange
der abhängige Controller fortfährt Daten der Reihe nach
aus Speicherbereichen zu lesen oder zu schreiben.
Bus-Mastering findet man in einigen SCSI-Controllern und
anderen hochwertigen Peripherie-Controllern.
Autoinitialize
Dieser Modus veranlasst den DMA-Controller dazu Byte-, Block- oder
Demand-Transfers auszuführen. Aber wenn der DMA-Zähler Null
erreicht hat, dann werden die Zähler und Adressen wieder auf den
Wert zurückgesetzt, den sie aufwiesen, als der DMA-Kanal ursprünglich
programmiert wurde. Daß bedeutet, daß Transfers zugelassen werden,
solange das Peripheriegerät sie anfordert. Es ist Aufgabe der CPU
neue Daten im Vorgriff in den Puffer zu schicken, damit das
Peripheriegerät sie schreiben kann bzw. die neuen Daten aus dem
Puffer zu lesen, wenn der DMA-Controller bei Eingabeoperationen
Daten schreibt.
Diese Technik wird häufig bei Audiogeräten genutzt, die
kleine oder gar keine Muster
-Puffer in Hardware
aufweisen. Dadurch entsteht zusätzlicher CPU-Overhead bei der
Abarbeitung dieser zirkulären
Puffer, aber in
manchen Fällen ist es der einzige Weg, um die Latenz zu
beseitigen, die auftritt, wenn der DMA-Zähler Null erreicht
und der DMA-Controller mit den Transfers anhält, bis er neu
programmiert ist.
Das Programmieren des DMA-Controllers
Der zu programmierende DMA-Kanal sollte immer
maskiert
werden, bevor irgendwelche Einstellungen
geladen werden. Dies soll deswegen geschehen, weil die Hardware
unerwarteterweise DRQ für diesen Kanal setzen könnte und der Controller
könnte antworten, obwohl noch nicht alle Parameter geladen oder
aktualisiert wurden.
Nach der Maskierung muß der Host die Richtung des Transfers festlegen
(Speicher-zu-I/O oder I/O-zu-Speicher), welcher DMA-Modus für den Transfer
genutzt wird (Single, Block, Demand, Cascade, etc) und schliesslich die
Adresse und die Länge des Transfers werden geladen. Die Länge ist um 1
kleiner als die durch den DMA-Controller zu transferirende. Der LSB und
der MSD der Adresse und die Länge werden auf den gleichen 8 Bit I/O-Port
geschrieben, also muß zunächst ein anderer Port geschrieben werden, um zu
Gewährleisten, daß der DMA-Controller das erste Byte als LSB und das zweite
Byte als MSB der Länge und der Adresse akzeptiert.
Stellen Sie dann sicher, daß Sie das Seitenregister aktualisiert haben,
welches extern zum DMA-Controller ist, und durch ein anderes Set von
I/O-Ports angesprochen wird.
Sobald alle Einstellungen fertig sind kann der DMA-Kanal demaskiert
werden. Dieser Kanal wird nun als geschützt
betrachtet und
wird antworten, wenn die DRQ-Linie für diesen Kanal eingefügt wird.
Schlagen Sie im Hardware Handbuch für ausführliche Programmierdetails
zum 8237 nach. Sie müssen sich auch auf die I/O-Portübersicht für den PC
beziehen, welches beschreibt, wo die DMA-Register und Seitenregister
sich befinden. Eine vollständige Tabelle der Ports finden Sie unten.
DMA Port-Übersicht
Alle Systeme basierend auf dem IBM-PC und PC/AT weisen die gleiche DMA-Hardware
an identischen I/O-Ports auf. Die vollständige Liste ist unten aufgeführt.
Dem DMA-Controller #2 zugewiesene Ports sind nicht definiert auf nicht-AT
-Systemen.
0x00–0x1f DMA-Controller #1 (Kanäle 0, 1, 2 und
3)
DMA Adress- und Zähl-Register
0x00
write
Kanal 0 Startadresse
0x00
read
Kanal 0 gegenwärtige Adresse
0x01
write
Kanal 0 beginnender Word-Zähler
0x01
read
Kanal 0 verbleibender Word-Zähler
0x02
write
Kanal 1 Startadresse
0x02
read
Kanal 1 gegenwärtige Adresse
0x03
write
Kanal 1 beginnender Word-Zähler
0x03
read
Kanal 1 verbleibender Word-Zähler
0x04
write
Kanal 2 Startadresse
0x04
read
Kanal 2 gegenwärtige Adresse
0x05
write
Kanal 2 beginnender Word-Zähler
0x05
read
Kanal 2 verbleibender Word-Zähler
0x06
write
Kanal 3 Startadresse
0x06
read
Kanal 3 gegenwärtige Adresse
0x07
write
Kanal 3 beginnender Word-Zähler
0x07
read
Kanal 3 verbleibender Word-Zähler
DMA-Befehlsregister
0x08
write
Befehlsregister
0x08
read
Status-Register
0x09
write
Anforderungsregister
0x09
read
-
0x0a
write
Single Mask Register Bit
0x0a
read
-
0x0b
write
Modusregister
0x0b
read
-
0x0c
write
Lösche LSB/MSB Flip-Flop
0x0c
read
-
0x0d
write
Master Clear/Reset
0x0d
read
Temporäres Register (nicht verfügbar in neueren
Versionen).
0x0e
write
Läsche Mask-Register
0x0e
read
-
0x0f
write
Lösche alle Mask-Register-Bits
0x0f
read
Lese alle Mask-Register-Bits (nur auf &intel;
82374)
0xc0–0xdf DMA-Controller #2 (Kanals 4, 5, 6 and
7)
DMA Adressen- und Zählerregister
0xc0
write
Kanal 4 Startadresse
0xc0
read
Kanal 4 gegenwärtige Adresse
0xc2
write
Kanal 4 beginnender Word-Zähler
0xc2
read
Kanal 4 verbleibender Word-Zähler
0xc4
write
Kanal 5 Startadresse
0xc4
read
Kanal 5 gegenwärtige Adresse
0xc6
write
Kanal 5 beginnender Word-Zähler
0xc6
read
Kanal 5 verbleibender Word-Zähler
0xc8
write
Kanal 6 Startadresse
0xc8
read
Kanal 6 gegenwärtige Adresse
0xca
write
Kanal 6 beginnender Word-Zähler
0xca
read
Kanal 6 verbleibender Word-Zähler
0xcc
write
Kanal 7 Startadresse
0xcc
read
Kanal 7 gegenwärtige Adresse
0xce
write
Kanal 7 beginnender Word-Zähler
0xce
read
Kanal 7 verbleibender Word-Zähler
DMA Befehlsregisters
0xd0
write
Befehlsregister
0xd0
read
Status-Register
0xd2
write
Anforderungsregister
0xd2
read
-
0xd4
write
Einzelnes Mask-Register-Bit
0xd4
read
-
0xd6
write
Modusregister
0xd6
read
-
0xd8
write
Lösche LSB/MSB Flip-Flop
0xd8
read
-
0xda
write
Master Clear/Reset
0xda
read
temporäres Register (nicht verfügbar auf &intel;
82374)
0xdc
write
Lösche Mask-Register
0xdc
read
-
0xde
write
Schreibe alle Mask-Register-Bits
0xdf
read
Lese alle Mask-Register-Bits (nur auf &intel;
82374)
0x80–0x9f DMA-Seitenregister
0x87
r/w
Kanal 0 niederes Byte (23-16) Seitenregister
0x83
r/w
Kanal 1 niederes Byte (23-16) Seitenregister
0x81
r/w
Kanal 2 niederes Byte (23-16) Seitenregister
0x82
r/w
Kanal 3 niederes Byte (23-16) Seitenregister
0x8b
r/w
Kanal 5 niederes Byte (23-16) Seitenregister
0x89
r/w
Kanal 6 niederes Byte (23-16) Seitenregister
0x8a
r/w
Kanal 7 niederes Byte (23-16) Seitenregister
0x8f
r/w
niederes Byte Seitenauffrischung
0x400–0x4ff 82374 Erweiterte DMA-Register
Der &intel; 82374 EISA System Component (ESC) wurde Anfang 1996
eingeführt und beinhaltet einen DMA-Controller, der die Funktionen
des 8237 aufweist und zusätzlich andere PC-kompatible Kern
-Peripheriekomponenten in einem einzigen Chip. Dieser Chip wurde
für EISA und PCI-Plattformen entworfen und stellt moderne DMA-Merkmale
wie Scatter-Gather, Ring-Puffer und direkten Zugriff des DMA-Controllers
auf alle 32 Bit des Adressraumes zur Verfügung.
Werden diese Leistungsmerkmale genutzt, dann sollte Code hinzugefügt
werden, der die gleiche Funktionalität für Geräte aus den 16 Jahren
PC-kompatibler Geräte vor diesem Chip zur Verfügung stellt.
Aus Kompatibilitätsgründen müssen einige der Register des 82374
programmiert werden nach der Programmierung der
traditionellen Register des 8237 für jeden Transfer. Das Schreiben
auf eines der traditionellen 8237-Register führt dazu, daß einige der
erweiterten Register des 82374 auf Null gesetzt werden aus
Kompatibilitätsgründen.
0x401
r/w
Kanal 0 hohes Byte (Bits 23-16) Word-Zähler
0x403
r/w
Kanal 1 hohes Byte (Bits 23-16) Word-Zähler
0x405
r/w
Kanal 2 hohes Byte (Bits 23-16) Word-Zähler
0x407
r/w
Kanal 3 hohes Byte (Bits 23-16) Word-Zähler
0x4c6
r/w
Kanal 5 hohes Byte (Bits 23-16) Word-Zähler
0x4ca
r/w
Kanal 6 hohes Byte (Bits 23-16) Word-Zähler
0x4ce
r/w
Kanal 7 hohes Byte (Bits 23-16) Word-Zähler
0x487
r/w
Kanal 0 hohes Byte (Bits 31-24) Seitenregister
0x483
r/w
Kanal 1 hohes Byte (Bits 31-24) Seitenregister
0x481
r/w
Kanal 2 hohes Byte (Bits 31-24) Seitenregister
0x482
r/w
Kanal 3 hohes Byte (Bits 31-24) Seitenregister
0x48b
r/w
Kanal 5 hohes Byte (Bits 31-24) Seitenregister
0x489
r/w
Kanal 6 hohes Byte (Bits 31-24) Seitenregister
0x48a
r/w
Kanal 6 hohes Byte (Bits 31-24) Seitenregister
0x48f
r/w
hohes Byte Seitenauffrischung
0x4e0
r/w
Kanal 0 Halteregister (Bits 7-2)
0x4e1
r/w
Kanal 0 Halteregister (Bits 15-8)
0x4e2
r/w
Kanal 0 Halteregister (Bits 23-16)
0x4e4
r/w
Kanal 1 Halteregister (Bits 7-2)
0x4e5
r/w
Kanal 1 Halteregister (Bits 15-8)
0x4e6
r/w
Kanal 1 Halteregister (Bits 23-16)
0x4e8
r/w
Kanal 2 Halteregister (Bits 7-2)
0x4e9
r/w
Kanal 2 Halteregister (Bits 15-8)
0x4ea
r/w
Kanal 2 Halteregister (Bits 23-16)
0x4ec
r/w
Kanal 3 Halteregister (Bits 7-2)
0x4ed
r/w
Kanal 3 Halteregister (Bits 15-8)
0x4ee
r/w
Kanal 3 Halteregister (Bits 23-16)
0x4f4
r/w
Kanal 5 Halteregister (Bits 7-2)
0x4f5
r/w
Kanal 5 Halteregister (Bits 15-8)
0x4f6
r/w
Kanal 5 Halteregister (Bits 23-16)
0x4f8
r/w
Kanal 6 Halteregister (Bits 7-2)
0x4f9
r/w
Kanal 6 Halteregister (Bits 15-8)
0x4fa
r/w
Kanal 6 Halteregister (Bits 23-16)
0x4fc
r/w
Kanal 7 Halteregister (Bits 7-2)
0x4fd
r/w
Kanal 7 Halteregister (Bits 15-8)
0x4fe
r/w
Kanal 7 Halteregister (Bits 23-16)
0x40a
write
Kanal 0-3 Chaining-Modusregister
0x40a
read
Kanal Interrupt Status-Register
0x4d4
write
Kanal 4-7 Chaining-Modusregister
0x4d4
read
Chaining Mode-Status
0x40c
read
Chain Buffer Expiration Kontrollregister
0x410
write
Kanal 0 Scatter-Gather Befehlsregister
0x411
write
Kanal 1 Scatter-Gather Befehlsregister
0x412
write
Kanal 2 Scatter-Gather Befehlsregister
0x413
write
Kanal 3 Scatter-Gather Befehlsregister
0x415
write
Kanal 5 Scatter-Gather Befehlsregister
0x416
write
Kanal 6 Scatter-Gather Befehlsregister
0x417
write
Kanal 7 Scatter-Gather Befehlsregister
0x418
read
Kanal 0 Scatter-Gather Statusregister
0x419
read
Kanal 1 Scatter-Gather Statusregister
0x41a
read
Kanal 2 Scatter-Gather Statusregister
0x41b
read
Kanal 3 Scatter-Gather Statusregister
0x41d
read
Kanal 5 Scatter-Gather Statusregister
0x41e
read
Kanal 5 Scatter-Gather Statusregister
0x41f
read
Kanal 7 Scatter-Gather Statusregister
0x420-0x423
r/w
Kanal 0 Scatter-Gather Descriptor Table Pointer
Register
0x424-0x427
r/w
Kanal 1 Scatter-Gather Descriptor Table Pointer
Register
0x428-0x42b
r/w
Kanal 2 Scatter-Gather Descriptor Table Pointer
Register
0x42c-0x42f
r/w
Kanal 3 Scatter-Gather Descriptor Table Pointer
Register
0x434-0x437
r/w
Kanal 5 Scatter-Gather Descriptor Table Pointer
Register
0x438-0x43b
r/w
Kanal 6 Scatter-Gather Descriptor Table Pointer
Register
0x43c-0x43f
r/w
Kanal 7 Scatter-Gather Descriptor Table Pointer
Register