Memory- und I/O-Bereiche Sämtliche Routinen, die für die Zugriffe auf Memory- und I/O-Bereich zuständig sind, berücksichtigen dabei auch das entsprechende Speicherformat (d.h. Intel/Motorola) der vorliegenden Resource. Für den Aufrufer dieser Funktion sieht es dann so aus, als würde es sich immer um das hauseigene (Motorola-) Format handeln. Ein Treiber kann also diese Funktionen benutzen, um auf Register bzw. kleinere Speicherbereiche zuzugreifen. Für größere Speicherbereiche kann es unter Umständen günstiger sein, unter Berücksichtigung der mittels get_resource zur Verfügung gestellten Informationen, eigene Kopierroutinen zu schreiben. Prinzipiell kann es ja auch mehrere voneinander unabhängige Memory- bzw. I/O-Bereiche geben. Was soll denn dies nun wieder heißen? Tja, erstens müssen z.B. die Memory-Bereiche mehrerer PCI-Geräte im Speicher nicht unbedingt hintereinander zu liegen kommen, und zweitens können in der betroffenen Hardware auch zwei voneinander physikalisch getrennte PCI-Busse vorliegen. Die Berücksichtigung dieser Umstände ist aber Aufgabe eines PCI-BIOS und der Anwender braucht sich darüber überhaupt keine Sorgen zu machen. Um jetzt aber doch ein wenig Verwirrung zu stiften, möchte ich noch erwähnen, dass ein PCI-Gerät ja auch mehrere typgleiche Resourcen (Memory und/oder I/O) belegen kann. Und diese Gegebenheit kann vom PCI-BIOS leider nicht selbständig berücksichtigt werden. Wie sollte das PCI-BIOS auch selbst "erahnen", welchen von mehreren möglichen Bereichen man nun ansprechen möchte. Die Auswahl der entsprechenden Resource ist somit in der in den Routinen verwendeten Zugriffsadresse miteinzubeziehen. Hier hilft uns dann wohl nur noch ein Beispiel weiter: Belegt ein PCI-Gerät z.B. zwei I/O-Bereiche, sind deren Startadressen über get_resource zu ermitteln (nennen wir sie Startadresse1 und Startadresse2). Wollen wir nun ein Register im zweiten I/O-Bereich ansprechen, so addieren wir zur gewünschten Registeradresse (Offset vom Beginn des betroffenen I/O-Bereichs) die Startadresse2 und erhalten somit die für die Routinen notwendige Zugriffsadresse. Selbige Vorgangsweise ist auch notwendig, wenn nur eine typgleiche Resource vorhanden ist. In diesem Fall wäre eben immer Startadresse1 zur gewünschten Registeradresse zu addieren. Memory Read Diese drei Funktionen erlauben also Lesezugriffe auf den Memory-Bereich unter Berücksichtigung des vorliegenden Speicherformats (d.h. Intel/Motorola). Aufruf in Assembler: Eingang: D0.L Geräte-Handle des gewünschten PCI-Gerätes D1.L Zugriffsadresse (Offset innerhalb des Memory-Adreßbereichs) A0.L Zeiger auf Ergebnisvariable Ausgang: D0.L PCI-BIOS Fehlercode gelesene Daten stehen nach dem Aufruf in der Ergebnisvariable Aufruf in C: LONG errorcode = read_mem_byte (LONG handle, ULONG offset, UBYTE *adresse) LONG errorcode = read_mem_word (LONG handle, ULONG offset, UWORD *adresse) LONG errorcode = read_mem_longword (LONG handle, ULONG offset, ULONG *adresse) handle: Geräte-Handle des gewünschten PCI-Gerätes offset: Zugriffsadresse (Offset innerhalb des Memory-Adreßbereichs) adresse: Zeiger auf Ergebnisvariable Returnwert: PCI-BIOS Fehlercode FAST Memory Read