Rockchip · AI & Linux Hub

Linux und Boot

Rockchip Linux IOMMU V1/V2: Seitentabellen, DMA-Zuordnung und Fehlersuche

Vollständige Aufbereitung auf Grundlage der chinesischen V1.2.0 mit V2-Seitentabellen, RK3588-Dumps, DMA/DRM/System-Heap und allen 18 FAQ-Abschnitten.

· ArmSoM Editorial · Rockchip source documentation · 17 Min. Lesezeit

Anwendbarkeit auf ArmSoM und Geltungsbereich der Quelle

Plattformreferenz zur Anpassung von ArmSoM-Systemen auf Grundlage der chinesischen V1.2.0 im Vergleich zur englischen V1.0.1. Keine Kombination aus Board, SDK/BSP, Kernel oder Verdrahtung wurde hier auf Hardware geprüft. Der nachstehende Geltungsbereich der Quelle bedeutet nicht, dass jedes ArmSoM-Board oder jeder Kernel diese Funktionen unterstützt. Prüfen Sie den genauen SoC, den Board-Schaltplan, SDK/BSP, Kernel-Treiber und Pinmux. Befehle, Patches, Protokolle und Messungen sind Quellbeispiele, keine ArmSoM-Testergebnisse.

Mit Zustimmung des Nutzers folgen alle Sprachen der chinesischen V1.2.0, einschließlich V2-Layouts, RK3588-Seitentabellen-Dumps, System-Heap-Zuordnung und FAQ 5.9–5.18, die in der englischen V1.0.1 fehlen. Ergänzungen behalten Kommentare mit chinesischen Quellseiten bei. Englisch, Russisch und Deutsch verwenden für die vier gemeinsamen Abbildungen die passenden englischen Originale; die beiden V2-Abbildungen stammen aus dem chinesischen Original, da keine englische Entsprechung vorliegt. Die älteren englischen Formeln verwenden &&, während Chinesisch & verwendet; Grundlage sind die chinesischen Ausdrücke, beide Varianten sind im Redaktionsprotokoll dokumentiert.

SoC laut Quelle Kernel-Geltungsbereich laut Quelle
ROCKCHIP 4.4/4.19/5.10/6.1

Die IOMMU übersetzt virtuelle 32-Bit-Adressen in physische Adressen, stellt Lese-/Schreibberechtigungsbits bereit und kann Interrupts für Seitenfehler sowie Busausnahmen auslösen.

Redaktionelle Hinweise · ArmSoM-Dokumentation · Rockchip Linux

1. IOMMU-Aufbau

Es wird eine zweistufige Seitentabellenstruktur verwendet:

Zweistufige IOMMU-Seitentabellenstruktur — englisches Quell-PDF S.6

Zweistufige IOMMU-Seitentabellenstruktur — englisches Quell-PDF S.6.

Felder einer virtuellen 32-Bit-IOMMU-Adresse — englisches Quell-PDF S.6

Felder einer virtuellen 32-Bit-IOMMU-Adresse — englisches Quell-PDF S.6.

Die 32-Bit-Adresse enthält einen 10-Bit-Versatz in der Tabelle erster Ebene, einen 10-Bit-Versatz in der Tabelle zweiter Ebene und einen 12-Bit-Versatz innerhalb der Seite.

DTE-Aufbau:

DTE-Layout der IOMMU V1 — englisches Quell-PDF S.6

DTE-Layout der IOMMU V1 — englisches Quell-PDF S.6.

V2-DTE-Aufbau (chinesische Quelle V1.2.0):

DTE-Layout der IOMMU V2 — chinesisches Quell-PDF S.4

DTE-Layout der IOMMU V2 — chinesisches Quell-PDF S.4.

bit0: Gibt an, ob die Seitentabelle der nächsten Ebene vorhanden ist.

PTE-Aufbau:

PTE-Layout und Berechtigungen der IOMMU V1 — englisches Quell-PDF S.7

PTE-Layout und Berechtigungen der IOMMU V1 — englisches Quell-PDF S.7.

bit0: Gibt an, ob die physische Seite vorhanden ist.

bit1: Leseberechtigung.

bit2: Schreibberechtigung.

V2-PTE-Aufbau (chinesische Quelle V1.2.0):

PTE-Layout der IOMMU V2 — chinesisches Quell-PDF S.5

PTE-Layout der IOMMU V2 — chinesisches Quell-PDF S.5.

Der vorstehende V1-Text nennt bit1=Lesen und bit2=Schreiben, die V2-Abbildung beschriftet dagegen bit2=Leseberechtigung und bit1=Schreibberechtigung (bit0=Seite vorhanden). Dieser versionsabhängige Unterschied bleibt exakt wie gezeigt erhalten. Übertragen Sie V1-Berechtigungen nicht ungeprüft auf V2; prüfen Sie den passenden Treiber beziehungsweise das TRM. Es erfolgte keine Hardwarevalidierung.

2. IOMMU-Treiber

2.1 Treiberdatei

Pfad der Treiberdatei:

drivers/iommu/rockchip-iommu.c

2.2 DTS-Knoten konfigurieren

Die DTS-Konfiguration ist in Documentation/devicetree/bindings/iommu/rockchip,iommu.txt beschrieben. Die wichtigsten Parameter folgen:

compatible = "rockchip,iommu";

compatible = "rockchip,iommu-v2"; — V2 aus der chinesischen Quelle V1.2.0.

Laut Quelle verwenden die IOMMUs der Geräte denselben compatible-Wert. Für Ausnahmeinterrupts wie Seitenfehler nennt sie interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH 0>;. Das Beispiel bleibt erhalten und ist gegen das tatsächliche DTS-Binding zu prüfen; oben enthält die Quelle sowohl V1- als auch V2-compatible-Zeichenfolgen.

clocks = <&cru ACLK_VOP1>, <&cru HCLK_VOP1>;

clock-names = "aclk", "hclk"; — IOMMU und Master teilen sich Takte; diese Einträge ermöglichen dem IOMMU-Treiber deren unabhängige Steuerung.

power-domains = <&power RK3399_PD_VOPL>; — ermöglicht Power-Domain-Operationen im IOMMU-Treiber.

iommu-cells = <0>; — die Quelle verlangt 0; siehe iommu.txt. Das fehlende # in dieser Quellschreibweise bleibt erhalten und ist im Redaktionsprotokoll markiert.

3. IOMMU verwenden

Der Rockchip-IOMMU-Treiber hängt vom IOMMU-Framework ab:

drivers/iommu/iommu.c

Er implementiert hauptsächlich Rückruffunktionen in:

struct iommu_ops rk_iommu_ops

Der Master ruft die Framework-APIs auf, um die IOMMU wie folgt zu steuern:

1. iommu attach

iommu_attach_device -> rk_iommu_attach_device /* enable iommu */

2. iommu detach

iommu_detach_device -> rk_iommu_detach_device /* disable iommu */

3. iommu map

iommu_map -> rk_iommu_map

Erstellt Seitentabellen und Zuordnungen zwischen virtuellen und physischen Adressen. Aktivieren Sie bei der Fehlersuche die dbg-Ausgabe in iommu_map, um die Zuordnung zu beobachten.

4. iommu unmap

iommu_unmap -> rk_iommu_unmap

Entfernt die Zuordnungen zwischen virtuellen und physischen Adressen und gibt virtuellen Adressraum frei. Aktivieren Sie die dbg-Ausgabe in iommu_unmap, um das Aufheben der Zuordnung zu beobachten.

5. domain alloc

iommu_domain_alloc -> rk_iommu_domain_alloc

Weist die von attach/detach verwendete Seitentabellen-Basisadresse zu.

6. domain free

iommu_domain_free -> rk_iommu_domain_free

Gibt den Seitentabellenspeicher frei.

7. IOMMU-Seitentabellen ausgeben. Für RK3399 vopl_iommu und die virtuelle Adresse VA=0x00001000 gilt folgender Ablauf. a. Tabellenbasis DT der ersten Ebene ermitteln:

io -4 0xff8f3f00

b. Tabellenversatz der ersten Ebene berechnen:

index1 = VA >> 22

c. Physische Adresse des Eintrags erster Ebene DTE berechnen:

DTE = index1 * 4 + DT

d. Tabellenbasis PT der zweiten Ebene ermitteln:

PT = io -4 DTE

e. Tabellenversatz der zweiten Ebene berechnen:

index2 = VA & 0x3ff000

f. Physische Adresse des Eintrags zweiter Ebene PTE berechnen:

PTE = index2 * 4 + PT

g. Physische PAGE-Adresse page ermitteln:

page = io -4 PTE

h. Versatz innerhalb der Seite offset berechnen:

offset = page + (VA & 0xfff)

Die Quelle bezeichnet offset als die physische Adresse zur virtuellen Adresse 0x00001000; der Master kann dort Daten untersuchen. Für RK3588 vop_mmu mit VA=0x00001000 ergänzt die chinesische V1.2.0 folgenden Ablauf. a. Tabellenbasis DT der ersten Ebene ermitteln:

DT = io -4 0xfdd97e00
DT = ((DT & 0xf0) << 32) | ((DT & 0xf00) << 24) | (DT & 0xfffff000)

b. Tabellenversatz der ersten Ebene berechnen:

index1 = VA >> 22

c. Physische Adresse DTE berechnen:

DTE = index1 * 4 + DT

d. Tabellenbasis PT der zweiten Ebene ermitteln:

PT = io -4 DTE
PT = ((PT & 0xf0) << 32) | ((PT & 0xf00) << 24) | (PT & 0xfffff000)

e. Tabellenversatz der zweiten Ebene berechnen:

index2 = VA & 0x3ff000

f. Physische Adresse PTE berechnen:

PTE = index2 * 4 + PT

g. Physische Seitenadresse page ermitteln:

page = io -4 PTE
page = ((page & 0xf0) << 32) | ((page & 0xf00) << 24) | (page & 0xfffff000)

h. offset berechnen:

offset = page + (VA & 0xfff)

Die Quelle bezeichnet offset als die physische Adresse zu VA=0x00001000; der Master kann damit Daten untersuchen. Die Formeln sind wörtlich übernommen und wurden nicht auf Hardware geprüft.

8. dma-mapping. a. Bei einem Gerät ohne IOMMU:

ARM32: dev->dma_ops = arm_dma_ops;
ARM64: dev->dma_ops = arm64_swiotlb_dma_ops;

b. Bei einem IOMMU-Gerät:

ARM32: dev->dma_ops = iommu_ops;
ARM64: dev->dma_ops = iommu_dma_ops;

Am Beispiel dma_alloc_attrs:

1. Bei einem Gerät ohne IOMMU weist die alloc-Rückruffunktion der dma_ops aus (a) zusammenhängenden physischen Speicher und eine virtuelle Kernel-Adresse zu.

2. Bei einem IOMMU-Gerät weist alloc in den dma_ops aus (b) physischen Speicher zu und ruft über das Framework iommu_map auf, um Seitentabellen und Zuordnungen zwischen virtuellen und physischen Adressen zu erstellen. Zurückgegeben werden die anfängliche virtuelle IOMMU-Adresse und die virtuelle Kernel-Adresse.

Minimaler Ablauf zur IOMMU-Nutzung:

1. domain = iommu_domain_alloc(&platform_bus_type);
2. iommu_map(domain, iova, paddr, size, prot);
3. iommu_attach_device(domain, dev);
4. master启动访问iommu

Die IOMMU ist eine Basiskomponente, die sich in Allokatoren wie ion/drm einbetten lässt. Unter ARM64 DRM lautet ein vollständiger Ablauf zur IOMMU-Pufferzuweisung und -zuordnung:

rockchip_gem_alloc_buf ->
rockchip_gem_get_pages ->
rockchip_gem_iommu_map ->
iommu_map_sg ->
iommu_map

IOMMU-Zuordnung bei Übergabe eines fd:

DRM-Pfad:

1. struct dma_buf *dmabuf = dma_buf_get(fd) ->
dma_buf_attach -> dma_buf_map_attachment ->
map_dma_buf -> drm_gem_map_dma_buf ->
dma_map_sg_attrs -> map_sg ->
__iommu_map_sg_attrs ->
iommu_dma_map_sg ->
iommu_map_sg ->
iommu_map

SYSTEM-HEAP-Pfad:

2. struct dma_buf *dmabuf = dma_buf_get(fd) ->
dma_buf_attach -> dma_buf_map_attachment ->
map_dma_buf -> system_heap_map_dma_buf ->
dma_map_sgtable -> __dma_map_sg_attrs ->
map_sg -> iommu_dma_map_sg ->
iommu_map_sg_atomic ->
__iommu_map_sg ->
__iommu_map

4. Kernel-Konfiguration

Symbol: ROCKCHIP_IOMMU [=y]
Type : boolean
Prompt: Rockchip IOMMU Support
    Location:
        -> Device Drivers
            -> IOMMU Hardware Support (IOMMU_SUPPORT [=y])
    Defined at drivers/iommu/Kconfig:211
    Depends on: IOMMU_SUPPORT [=y] && (ARM || ARM64 [=y]) && (ARCH_ROCKCHIP [=y] ||
                COMPILE_TEST [=n])
    Selects: IOMMU_API [=y] && ARM_DMA_USE_IOMMU

5. Häufige Fragen zur IOMMU

5.1 Seitenfehlerinterrupt

Ein Seitenfehlerinterrupt bedeutet, dass für die aktuell verwendete virtuelle Adresse keine Zuordnung existiert. Bei Mastern traten drei Fälle auf: Zugriff auf eine nicht zugeordnete Adresse, Zugriff außerhalb der Grenzen oder Zugriffsbeginn vor Erstellung der Zuordnung.

5.2 Fehler bei IOMMU enable-stall

Möglicherweise ist bereits ein IOMMU-Seitenfehler aufgetreten, und der Master greift ohne dessen Behandlung weiter zu; prüfen Sie das Protokoll.

Auch eine fehlerhafte Taktsteuerung ist möglich. Lassen Sie PD und CLK vorübergehend aktiviert, um diese Ursachen auszuschließen.

5.3 IOMMU-Register nicht erreichbar

Die Power-Domain-Verwaltung des Masters verwendet möglicherweise pm_runtime_get_sync/pm_runtime_put_sync falsch und greift auf IOMMU-Register zu, bevor die IOMMU-Power-Domain aktiviert ist.

5.4 Fortlaufende IOMMU-Interrupts

Die Interruptnummer im DTS kann falsch sein.

Der Master greift möglicherweise ständig auf nicht zugeordnete IOVA zu; häufig treten dabei Anzeigefehler auf.

5.5 Flackern der Anzeige beim Start

Das Aktivieren der IOMMU während einer laufenden VOP-Anzeige kann das Einlesen der Bilddaten stören. Bei Chips ohne zum Frame-Wechsel wirksame Umschaltung muss vor dem Aktivieren gewartet werden, bis VOP keine Daten abruft.

5.6 Fehlerhafte IOMMU-Register

Grenzüberschreitende Zugriffe des Masters auf IOMMU-Register können dieses Problem verursachen.

Ein Reset des gesamten Master-IP-Blocks setzt auch die IOMMU zurück, da sie in diesen IP-Block integriert ist.

Stellen Sie nach einem Master-Reset die IOMMU-Registerkonfiguration wieder her.

Die Power-Domain-Steuerung wird an den Master übergeben; achten Sie auf die richtige Verwendung von pm_runtime_get/pm_runtime_put.

Ein Aufruf von pm_runtime_get im Master aktiviert die IOMMU.

Ein Aufruf von pm_runtime_put im Master deaktiviert die IOMMU.

5.8 Pflege der Seitentabellen

Unter ARM32 benötigen Master mit gemeinsam genutzter IOMMU, etwa vepu und vdpu, getrennte Seitentabellen und müssen vor jedem Zugriff die passende Tabelle anhängen. ARM64 verwendet gemeinsame Seitentabellen, daher ist wiederholtes attach nicht erforderlich.

5.9 Reset-Fehler bei hoher Taktfrequenz

RK3288-Neustart-Stresstests können VOP-Seitenfehler auslösen. Bei übertaktetem VOP kann der erzwungene Reset der VOP-IOMMU scheitern. Die Quelle umgeht dies, indem sie beim Anhängen der VOP-IOMMU den erzwungenen Reset überspringt.

5.10 VOP-IOMMU auf RK3128/RK3126 nicht lesbar

Die VOP-IOMMU-Register dieser Chips sind nicht lesbar. Ergänzen Sie folgenden Workaround in der DTS-Konfiguration der VOP-IOMMU:

rockchip,skip-mmu-read

Der Treiber überspringt die betreffenden Lesezugriffe; das Flag heißt iommu->skip_read.

5.11 Reset-Vorgang

Nach einem Reset der ISP-IOMMU bestätigt ihr Statusregister den Abschluss möglicherweise nicht, obwohl der Reset erfolgreich war. Ergänzen Sie folgenden Workaround im ISP-IOMMU-DTS-Knoten:

rockchip,disable-mmu-reset

Dadurch wird der ISP-IOMMU-Reset übersprungen; das Treiberflag heißt iommu->reset_disabled.

5.12 Wirksamkeit von Schreibbefehlen sicherstellen

Laut Quelle können bei der rkvenc-IOMMU von RK1126 und RV1109 Schreibbefehle verloren gehen; wiederholen Sie Schreibzugriffe mehrmals, um dies zu vermeiden. RK1126 bleibt wie im Original geschrieben erhalten und muss geprüft werden.

5.13 Automatisches Anhängen der VOP-IOMMU deaktivieren

Ab Kernel 4.19 hängt VOP die IOMMU explizit an, statt dies automatisch bei Registrierung des Geräteknotens zu tun. Dadurch werden Anzeigeprobleme beim Übergang von U-Boot zum Kernel vermieden.

5.14 Leistungseinbußen durch Leeren des IOMMU-TLB

Zuordnungen erfordern das Leeren des TLB. Fragmentierte Puffer können viele Leerungen verursachen und die Leistung senken; ergänzen Sie ein Flag, sodass der TLB nur einmal geleert wird.

5.15 Eins-zu-eins-Zuordnung für VOP-IOMMU

Eine Eins-zu-eins-Zuordnung vermeidet Anzeigefehler durch das Warten auf zum Frame-Wechsel wirksame Aktualisierungen beim Übergang zwischen U-Boot und Kernel. Beispielsweise hat RK356X mehr Master als IOMMUs, weshalb dieses Warten nicht verfügbar ist; eine Identitätsabbildung umgeht das Problem.

5.16 Ein Master mit zwei IOMMUs

Sofern keine besonderen Anforderungen bestehen, optimieren Sie den Master-Treiber so, dass beide IOMMUs dieselbe Seitentabelle verwenden.

Der neuere IOMMU-Treiber der Quelle verwendet für mehrere IOMMUs eines Masters automatisch dieselbe Seitentabelle; Eingriffe des Master-Treibers sind nicht erforderlich.

5.17 Zwischen H.264/H.265 auf PX30 umschalten

Verwenden Sie folgende Reihenfolge:

  1. Sicherstellen, dass alle Takte aktiviert sind.
  2. Sicherstellen, dass alle Power-Domains aktiviert sind.
  3. Alle IOMMUs deaktivieren.
  4. GRF umschalten.
  5. Aktuelle IOMMU aktivieren.

5.18 Fehler beim gleichzeitigen Betrieb von VPU und HEVC auf RK3368

RK3368-VPU und HEVC teilen sich einen IOMMU-TLB. Führen Sie TLB-Operationen und damit Zuordnungsoperationen seriell aus, um Fehler zu verhindern.

Dieses Thema entdecken → · Lernpfade →