Forum: Mikrocontroller und Digitale Elektronik Super I/O im FPGA und Linux Treiber


von Bernd G. (bege)


Lesenswert?

Hallo,

hier mal eine Frage an Alle, die sich mit der Programmierung von Linux 
Treibern auskennen.

Vorgeschichte:
Ich habe einen PowerPC mit Linux (Kernel 2.4) und ein FPGA, daß am 
externen BUS-Interface des PPCs hängt (memory mapped I/O). Das FPGA ist 
als I/O Subsystem gedacht und enthält schon diverse Schnittstellen 
(UARTS, Parallel Port, SPI, ect.) Nun soll es um ein IDE Interface 
erweitert werden.

Das Problem ist, daß alles was bisher im FPGA eingebaut ist nicht vom 
BUS-Timing des PPC abhängt. D.h. wenn ich z.B. den UART im FPGA 
ansprechen will, schreibe ich einfach vom PPC aus in ein Register des 
FPGAs und gut is.

Die IDE Schnittstelle ist aber langsamer als die Kommunkiation PPC <-> 
FPGA, d.h. ich kann die Zugriffe nicht einfach an die IDE Schnittstelle 
weiterleiten. Den Buszyklus des PPC kann ich nicht einfach verlängern.

Daher war mein Gedanke, ein komplettes IDE-Kommando erst einmal im FPGA 
zwischenzuspeichern, um es dann Stück für Stück an das IDE-Device zu 
übertragen (per Statemachine im FPGA). Nachdem das IDE-Device fertig 
ist, setzt es die Interrupt Leitung und das FPGA kopiert die 
Registerinhalte aus dem IDE-Device in den FPGA Speicher. Danach erzeugt 
es einen Interrupt auf PPC-Seite. Dieser liest dann das Ergebnis aus dem 
FPGA.

Wie bringe ich Linux bei, daß es genau auf diese Art und Weise (und auch 
nur so!) mit dem IDE-Device kommunizieren kann? In den Sourcen habe ich 
gesehen, daß Linux bestimmte IDE-Chipsätze kennt. Falls ein unbekannter 
Chipsatz konfiguriert ist, versucht der Kernel auf direktem Wege auf die 
IDE-Schnittstelle (bzw. die IDE-Device-Register) zuzugreifen, was in 
meinem Fall ja nicht geht (Bus-Timing).

Hat jemand so etwas schon einmal gemacht und kann mir eventuell sogar 
ein 'Framework' für den benötigten Linux IDE-Treiber zukommen lassen ?
Oder bin ich vielleicht total auf dem Holzweg und es geht viel einfacher 
als ich mir das gedacht habe ?

Ich danke Euch schon einmal für die konstruktiven Antworten!

Gruß Bernd

von Tobias P. (hubertus)


Lesenswert?

> was in meinem Fall ja nicht geht (Bus-Timing).

Ich kenn' mich zwar mit Linux nicht wirklich gut aus, mit Treibern schon 
gar nicht, ABER: Das Problem mit dem Bus-Timing besteht nicht nur bei 
dir. Die IDE-Schnittstelle ist natürlich allgemein langsamer als irgend 
ein Datenbus - oder denkst du, in deinem übertakteten Pentium 4 PC mit 4 
GHz ist die IDE-Schnittstelle grad ausreichend schnell, dass der 
Prozessor nie warten muss?

Du musst keine Waitstates oder sowas einfügen (kannst ja auch gar 
nicht). Betrachte einfach die paar Register von der HD wie ein (sehr 
kleines) RAM - paar Werte reinschreiben und dann was anderes machen, bis 
der Interrupt kommt.

von Bernd G. (bege)


Lesenswert?

Tobias Plüss wrote:
> Ich kenn' mich zwar mit Linux nicht wirklich gut aus, mit Treibern schon
> gar nicht, ABER: Das Problem mit dem Bus-Timing besteht nicht nur bei
> dir. Die IDE-Schnittstelle ist natürlich allgemein langsamer als irgend
> ein Datenbus - oder denkst du, in deinem übertakteten Pentium 4 PC mit 4
> GHz ist die IDE-Schnittstelle grad ausreichend schnell, dass der
> Prozessor nie warten muss?

Das ist mir schon klar nur beim PC ist da ja einiges zwischen Prozessor 
und IDE-Device (North Bridge -> PCI-Bus -> eventuell South Bridge -> IDE 
Controller). Es geht hier ja auch nicht um die Abarbeitung des Kommandos 
selbst, sondern um die Kommunikation mit dem IDE-Device. Mir ist ablout 
klar, dass z.B. das Lesen eines Blocks vom CD-ROM ewig dauern kann, 
daher ja auch der Interrupt nach Abarbeitung des Befehls.

> Du musst keine Waitstates oder sowas einfügen (kannst ja auch gar
> nicht). Betrachte einfach die paar Register von der HD wie ein (sehr
> kleines) RAM - paar Werte reinschreiben und dann was anderes machen, bis
> der Interrupt kommt.
FALSCH! Selbst der Zugriff auf die IDE-Register (Dein kleines RAM!) 
dauert länger (~120ms) als ein Buszyklus der (Pentium4@4GHz) CPU!
Die Frage ist doch, was macht der IDE Controller? Er muß die Zugriffe 
cachen, also schnell von der CPU annehmen und langsam an das IDE-Device 
senden. Oder eben mit Waitstates arbeiten, was natürlich im Vergleich 
zum CPU Takt extrem langsam ist!

Meine ursprüngliche Frage ziehlt eher darauf ab welche Features der 
IDE-Controller im FPGA haben muß und wie ich diese Features auch per 
Linux-Treiber nutzen kann, bzw. wie aufwendig die Entwicklung eines 
eigenen  IDE-Treibers ist.

So nebenbei:
Ich kenne keinen X86 Assembler Befehl, mit dem man das Lesen aus einem 
IO-Register anstößt und sich dann irgendwann später das Ergebnis abholt 
'inb' oder 'inw' können das jedenfalls nicht ;-)
Der Pentium arbeitet sehr wohl mit Wait-States, oder wie funktionierte 
das damals mit dem ISA-Bus (8MHz!) und sagen wir mal 200MHz CPU Takt.

Gruß Bernd

von *.* (Gast)


Lesenswert?

Man könnte es dennoch transparent machen...
(Ich kenne nur die alte 1F0-1F7/3F6-IDE-Schnittstelle, mein Geschreibsel 
bezieht sich also darauf).
Der FPGA speichert die Parameterregister, und sobald das Kommandobyte 
geschrieben wird pumpt er die Daten zur Festplatte. Währenddessen wird 
busy signalisiert. Wenn dann die Festplatte irgendwann mal fertig ist 
liest der FPGA den Status und Puffer der Festplatte aus (die Blockgröße 
muß evtl. begrenzt werden) und gibt dann den Interrupt, der Linux dazu 
veranlasst, Daten wie gewohnt abzuholen.

von SiO2 (Gast)


Lesenswert?

Bastle Dir doch ne eigene IDE-Schnittstelle im FPGA (als ob es eine 
echte wär), die dann vom Kernel auch wie eine angesprochen wird. Was 
dann innerhalb des FPGA passiert interessiert den Treiber nicht, nur 
Dich :P

von Bernd G. (bege)


Lesenswert?

Hallo SiO2,

prinzipiell ist das natürlich auch denkbar. Allerdings denke ich, dass 
das sehr aufwendig wird, im FPGA ein komplettes IDE-Device zu emulieren 
und ich sehe in diesem Ansatz noch ein anderes Problem:
Angenommen ich sage dem FPGA, es soll einen Datenblock lesen. Das FPGA 
nimmt den Befehl an (und erkennt, dass er syntaktisch korrekt ist). Dann 
setzt das FPGA im Status Register den Status "Kommando OK, Device Busy". 
Da aber keine CD im Laufwerk liegt, ist der Status des IDE-Devices auf 
Error.

Im FPGA würde immer ein gecachter Device-Status liegen, der unter 
Umständen nicht der Realität entspricht.

Meiner Meinung nach darf der Linux-Treiber nur zu genau festgelegten 
Zeitpunkten auf die IDE-Register zugreifen (immer nachdem das FPGA die 
Register vom IDE-Device gelesen hat).
Ich weiß nicht ob es im Linux-Treiber vorkommen kann, aber es wäre bei 
einer solchen Implementierung z.B. 'verboten' zwischendurch mal das 
IDE-Statusregister zu vom Treiber zu lesen.

Ich habe mir das in etwa so gedacht:

Treiber: IDE-Kommando-Sequenz ins FPGA schreiben
FPGA: Daten buffern bis Kommando-Sequenz vollständig
Treiber: Warten auf Interrupt
FPGA: Übertragen der Daten an das IDE-Device
FPGA: Warten auf Interrupt (oder Timeout)
FPGA: Interrupt erkannt, Daten vom IDE-Device ins FPGA übertragen
FPGA: Interrupt auf CPU auslösen
Treiber: Daten aus FPGA lesen, Status auswerten, ect.

Mit Daten meine ich in diesem Zusammenhang sämtliche IDE-Register plus 
den eigendlichen Nutzdatenblock.

Trotzdem bleibt das Problem, dass der Treiber nicht eben mal 
zwischendurch  Register des IDE-Devices auslesen darf (er würde immer 
den Zustand nach dem letzten Kommando bekommen). Die Frage ist ob/wie 
man das oben genannten Schema in einem Treiber umsetzen kann.

Ich werde mir mal die Treiber und die Datenblätter diverser Raid 
Controller anschauen, die müssen die einzelnen pyhsikalischen Platten ja 
auch irgendwie abstrahieren.

Gruß Bernd

von Matthias (Gast)


Lesenswert?

Schon mal das Projekt "OCIDEC (OpenCores IDE Controller): Overview"
auf opencores.org angeschaut? Wie machen die das?

von Tom (Gast)


Lesenswert?

Entschultige bitte Bernd, aber das was du hier treibst ist einfach nur 
gruselig. Wenn du "Standart" ATA Treiber benutzen willst dann würde ich 
die dringend empfehlen das entsprechende IDE Interface im FPGA zu 
implementieren, wie dir ja bereits empfohlen wurde.

> Angenommen ich sage dem FPGA, es soll einen Datenblock lesen. Das FPGA
> nimmt den Befehl an (und erkennt, dass er syntaktisch korrekt ist). Dann
> setzt das FPGA im Status Register den Status "Kommando OK, Device Busy".
> Da aber keine CD im Laufwerk liegt, ist der Status des IDE-Devices auf
> Error.

Der FPGA soll per Memory Mapped IO die Register zur verfügung stellen. 
Die syntaktische Prüfung des Befehls erledigt der Treiber. Der FPGA soll 
nicht orakeln sondern sich den Status vom Laufwerk, also über das IDE 
Interface holen.

Viel Erfolg,
Tom

von Bernd G. (bege)


Lesenswert?

@Matthias
OpenCores & Co benutzen Bussysteme, die Waitstates unterstützen da ist 
das alles kein Problem. Ich kann leider nicht mit Waitstates arbeiten 
(die verwendete CPU unterstützt das nicht), daher kann ich die Cores 
(und die Liunx Treiber) nicht direkt benutzen.

@Tom
> Der FPGA soll per Memory Mapped IO die Register zur verfügung stellen.
Und genau das geht ja nicht wegen des unterschiedlichen BusTimings und 
der fehlenden Möglichkeit die CPU mit Waitstates zu beaufschlagen. Die 
Requests müssen vom FPGA gecached werden nur das muß der Treiber auch 
wissen!

> Wenn du "Standart" ATA Treiber benutzen willst ...
Es kann kein "Standart" Treiber sein sondern ein selbstgeschriebener, 
der auf die Hardwarespezialitäten eingeht!

Gruß Bernd

von Bernd G. (bege)


Lesenswert?

Hallo zusammen,

habe gerade festgestellt, daß ich mit meinem Problem nicht alleine auf 
der Welt bin :-)

http://linux.derkeiler.com/Newsgroups/comp.os.linux.embedded/2006-08/msg00089.html

Leider gibt's dort auch noch keine Lösung...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.