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