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
> 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.
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
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.
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
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
Schon mal das Projekt "OCIDEC (OpenCores IDE Controller): Overview" auf opencores.org angeschaut? Wie machen die das?
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
@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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.