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 Rechner 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 übertragen, 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 gesamten 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 aufweisen, 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