Forum: FPGA, VHDL & Co. PCI DMA Master schreiben funktioniert nicht


von Markus H. (brainmine)


Lesenswert?

Ich habe einen vhdl pci master mit dma mit dem ich Daten mit einem ETX 
Modul (Intel N450 mit ICH8M chipsatz, PV-510 von MSC) via PCI Transfer 
austauschen möchte. Als Betriebssystem verwende ich das 
Echtzeitbetriebssystem Ontime. Folgende Funktionen reservieren 8 KByte 
Speicher für den PCI Transfer:

// gültig Adresse des Physikalischen Speichers
Physical= 0x04000000;

// speicher Reservieren
Virtual = RTReserveVirtualAddress(0, 8192, 0);

// phys. mit virt. Speicher Mappen, READ/WRITE USER MODE
RTMapMem(Physical, Virtual, 8192, RT_PG_USERREADWRITE);

Was geht:
schreibe ich (zufällige) Werte in Virtual und programmiere den DMA 
Master, dass er 8Kbyte  and Daten in Richtung internes Ram des FPGA 
transferiert funktioniert das ohne Probleme (Als PCI Adresse für den DMA 
transfer  verwende ich Physical=0x04000000).

Was nicht geht:
In die andere Richtung, d.h. von internen FPGA RAM lesen und in DDR RAM 
des ETX Modules schreiben (PCI Adresse ist wieder Physical=0x04000000) 
geht nicht. Ich sehe zwar, dass Daten transferriert werden (IRDY und 
TRDY aktiv), jedoch wird der Inhalt von Virtual nicht aktualisiert.

Vermutung: Cache wird nicht upgedatetd oder Problem mit Zugriffsrechent.

kann mir jemand weiterhelfen ?

von Lattice User (Gast)


Lesenswert?

Ich kenne Ontime nicht, aber unter Windows würde dein Vorgehen zu einem 
sehr üblen Crash führen.

Die Routinen die du verwendest dienen zum Bereitstellen einer virtuellen 
Adresse um auf eine gegebenen physikalische Addresse auf einer PCI Karte 
zuzugreifen (Memory Mapped IO),
Du kannst bei Windows nicht einfach hergehen und ein Stück 
physikalischen Hauptspeicher willkürlich als den deinen deklarieren, und 
dann als DMA Buffer benutzen. Ich vermute stark dass das bei Ontime auch 
der Fall ist.

Einen DMA Buffer alloziert man in etwa so:
vPtr = alloc_memory( size)
lock_memory(vPtr)
pSGList = get_SGList(vPtr)
pPtr = pSGList[0].pPtr
(Funktionsnamen sind reine Phantasie)

Im Allgemeinen ist der so allozierte physikalische Speicher nicht 
kontinuierlich, aber unter Windows gibt es Flags und Funktionen um das 
zu erreichen.

von Markus H. (brainmine)


Lesenswert?

Danke für die schnelle Antwort.

ich habe mich diesbezüglich direkt an ontim gewendet.

(link zu ontime: 
http://www.on-time.com/rtos-32-docs/rttarget-32/reference-manual/memory-mapping/rtreservevirtualaddress.htm 
)

zu Info:
RTReserveVirtualAddress entspricht malloc unter windows.
RTMapPhysMem liefert mir die dazugehörige physicalische addresse, die 
mein pci master benötigt.

Der Transfer von DDR RAM zum FPGA funktioniert wie gesagt ohne Probleme!

von Lattice User (Gast)


Lesenswert?

Markus Helbig schrieb:
> RTMapPhysMem liefert mir die dazugehörige physicalische addresse, die
> mein pci master benötigt.

Was soll dann:
1
Physical= 0x04000000;

Ich sehe auch keine Rückgabe der Physikalischen Adresse in deinem 
RTMapPhysMem Aufruf

> Der Transfer von DDR RAM zum FPGA funktioniert wie gesagt ohne Probleme!

Die Daten die da ankommen auch überpüft?

von Lattice User (Gast)


Lesenswert?

Du hast ja den Link zur relevanten Docu gepostet hast, habe es mir mal 
angeschaut.

Du musst den Speicher mit RTAllocPhysPageAligned allozieren.

von Markus H. (brainmine)


Lesenswert?

Physical= 0x04000000;
=> ist natürlich blödsinn (ich habe bereits mehrere Variation 
durchprobiert und dabei diese Passage mit kopiert)


jetzt verwende ich die vorgeschlagene Funktion :

Virtual=RTAllocPhysPageAligned(2048);
Physical = RTGetPhysAddress(Virtual);

Physical sollte identisch mit Virtual sein, was defakto auch so ist.

Transfer per DMA von ETX DDR RAM zum internen RAM des FPGA funktioniert. 
Die Daten habe ich auch überprüft.

Der Transfer von internen RAM zum ETX DDR RAM funktioniert leider immer 
noch nicht! (obwohl trdy und irdy während des Transfers aktiv sind- auch 
die Anzahl der Daten, d.h die nötige Zeit für den Transgfer stimmmt). Wo 
landen die Daten ?

jedenfalls nicht im  reserveirten Bereich (Virtual)

von Markus H. (brainmine)


Lesenswert?

Ich bin inzwischen soweit, dass ich vermute es liegt an der Bridge im 
ICH8M Chipsatz von Intel. (S.261 Decode Window)

Link:
http://www.intel.com/content/dam/doc/datasheet/intel-io-controller-hub-8-datasheet.pdf

muss mich mal reinlesen. Vielen Dank für die Hilfe bisher.

von Markus H. (brainmine)


Angehängte Dateien:

Lesenswert?

Hier nochmals eine Zusammenfassung:
ich habe das system nochmals graphisch dargestellt: (PV-510, mit 2 PCI 
Karten)
1.  Als Betriebssystem verwenden ein On Time
    (link zu ontime: 
http://www.on-time.com/rtos-32-docs/rttarget-32/re... )

2.  ich reserviere mir eine 8 Kbyte großen Speicherbereich
    die virtuelle Adress stimmt mit der physicalischen überein:
       Physical =RTAllocPhysPageAligned(8192);

3.  ich erzeuge 10 zufällige Worte und schreibe diese in den 
Haupspeicher:
      for(i=0;i<16;i++)
      {
         Value= rand()<<16|rand();
         *(Physical+i)=Value;
      }

4. Ich programmiere den DMA Controller zum Test  folgendermassen:

Diese 10 Worte aus dem DDR2 Speicher (Adresse Physical)  in DP  RAM des 
PCI Master transferieren =>funktioniert fehlerfrei, ich kann über pci 
den DP RAM auslesen und mit den Werten vergleichen)
for(i=0;i<16;i++)
{
  DrvSys_CPCI_Read(CPCIAddr_MASTER_DP_RAM + 0x00 + i*4,&Value,1);
  Buffer[i]=Value;
  if ( *( Physical + I + 0x00) != Buffer[i] )
    error++;
}

Diese 10 Worte aus dem DP RAM des PCI Master in den DP RAM des PCI 
Target transferieren => funktionert fehlerfrei, s.o.
for(i=0;i<16;i++)
{
  DrvSys_CPCI_Read(CPCIAddr_TARGET_DP_RAM + 0x00 + i*4,&Value,1);
  Buffer[i]=Value;
  if ( *( Physical + I + 0x00) != Buffer[i] )
    error++;
}

10 Worte aus dem DP RAM des PCI Master zum DDR2 (Adresse Physical + 
0x100)  transferieren => transfer findet statt, in Adresse Physical + 
0x100 hat sich aber nix geändert !

von Lattice User (Gast)


Lesenswert?

Ich glaube nicht dass es am ICH8 also solchen liegt, ich mache schon 
lange PCIexpress (seit ICH6) und hatte mit den ICHx noch nie Probleme 
wenn zusammen mit einer anständigen Intel CPU verwendet.

Mit Atoms sieht es etwas trüber aus, schon 2 mal Stress gehabt. Beides 
Mal hat es einen PCI Express analyzer gebraucht um den Fehler 
aufzufinden. (Ging aber nicht um DMA)

Sicherstellen dass dein DMA im FPGA korrekt ist, Test auf anderer 
Platform, stimmt das Timing (Analyzer, Chipscope, Simulator), etc etc.

von Markus H. (brainmine)


Lesenswert?

DMA Master dürfte nicht das Problem sein, da ich ja in die eine Richtung 
(DDR -> FPGA RAM) fehlerfrei übertragen kann. Die Richtung wird ja nur 
durch das PCI Kommando (Memory Read / Memory Write) festgelegt.

Außerdem funktioniert ja der Transfer FPGA RAM zu PCI Target RAM (hier 
unterscheidet sich nur die PCI Adresse).

ich glaube und hoffe, dass es an der physikalischen Adresse liegt, oder 
konfiguration von ICH8.

Ich kontaktiere mal MSC (ETX Board Hersteller, die geben guten 
Support)....

von Lattice User (Gast)


Lesenswert?

Markus Helbig schrieb:
> ich glaube und hoffe, dass es an der physikalischen Adresse liegt, oder
> konfiguration von ICH8.

Wage ich zu bezweifeln. Wenn etwas in der Richtung dann im Atom. Der 
Speicher ist am Atom angeschlossen, und nicht am ICH8.

von Lattice User (Gast)


Lesenswert?

Noch eine Frage

Markus Helbig schrieb:
> 10 Worte aus dem DP RAM des PCI Master zum DDR2 (Adresse Physical +
> 0x100)  transferieren => transfer findet statt, in Adresse Physical +
> 0x100 hat sich aber nix geändert !

Hast du einen Delay zwischen Transfer anstossen und Vergleich ob die 
Daten angekommen sind?

von Markus H. (brainmine)


Lesenswert?

Der DMA Transfer wird alle 50 us gestartet, den Inhalt vom ETX RAM sehe 
ich im Visual Studio 2010 memory window (Virtual ist die Startadresse).
Der Delay ist mein Brakepoint beim Debuggen...

> Wage ich zu bezweifeln. Wenn etwas in der Richtung dann im Atom. Der
> Speicher ist am Atom angeschlossen, und nicht am ICH8.

Der Speicher ist am Atom, aber die Bridge die das Routing macht ist im 
ICH8

von Lattice User (Gast)


Lesenswert?

Markus Helbig schrieb:
> Der Speicher ist am Atom, aber die Bridge die das Routing macht ist im
> ICH8

Das Routing klappt aber, sonst könntest du auch nicht lesen.
Entweder ist da ein Schreibschutz (Stichwort IOMMU, wobei ich nicht 
weiss ob der Atom oder andere IntelCPU eine hat, musste mich damit noch 
nicht beschäftigen), oder es gibt einen Protokollfehler, der Atom ist da 
etwas eigen.

von Markus H. (brainmine)


Lesenswert?

ich habe das ganze inzwischen mit einem Celeron M (SOM-4481) getestet.

Link http://www.advantech.com/applied/products/SOM-4481.pdf

Gleiches verhalten, lesen geht, schreiben geht nicht....

> Stichwort IOMMU: sowas gibt es



Link Intel N450
http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/atom-n400-vol-2-datasheet.pdf

Seite 12 Zitat:
"programmable attributes such as Disable, Read/Write, Write Only, or 
Read Only. Attribute programming is described in the Register 
Description section"

Das war ein guter Hinweis, mal durchlesen....

von Markus H. (brainmine)


Lesenswert?

ich habe mal das Status Register des Atom (PCI Device 0 Func 0) 
ausgelesen und folgendes festgestellt:

sobald ich vom FPGA richtung DDR RAM schreibe wird BIT 15 gesetzt:

BIT 15 : Detected Parity Error (DPE): This bit is set when this Device 
Deceives a Poisoned TLP.

Konfiguriere ich den DMA so dass er nur Daten vom DDR zum FPGA 
schauffelt wird dieses Bit nicht gesetzt.

Wenn er die Parität vom PCI 1:1 ins TLP übernimmt, liegt der Fehler wohl 
bei der Paritätserzeugung im FPGA PCI Master....mal schaun....

von Markus H. (brainmine)


Lesenswert?

Hallo Lattice User,
vielen Dank für die Anregungen. Es war tatsächlich ein Paritätsfehler. 
Der DMA Master läuft jetzt einwandfrei in Beide Richtungen!

Vielleicht sollte ich mir mal einen HW anlayser zulegen / selber bauen 
.-)

Vielen Dank für die Ideen
M.Helbig

von Lattice User (Gast)


Lesenswert?

Markus Helbig schrieb:
> Hallo Lattice User,
> vielen Dank für die Anregungen. Es war tatsächlich ein Paritätsfehler.
> Der DMA Master läuft jetzt einwandfrei in Beide Richtungen!

Gern geschehen, und danke für die Rückmeldung, so macht es Spass.

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.