Remove ads
offene Befehlssatzarchitektur Aus Wikipedia, der freien Enzyklopädie
RISC-V, offizielle Aussprache in Englisch: „risc-five“[1] [ ], ist eine Befehlssatzarchitektur (engl. instruction set architecture, ISA), die sich auf das Designprinzip des Reduced Instruction Set Computers (RISC) stützt. Es ist ein offener Standard, welcher der freien BSD-Lizenz unterliegt. Das bedeutet, dass RISC-V nicht patentiert ist und frei verwendet werden darf. Somit ist es jedem erlaubt, RISC-V Mikroprozessoren zu entwerfen, herzustellen, weiterzuentwickeln und zu verkaufen (Open-Source-Hardware).[2] Zahlreiche Unternehmen bieten RISC-V-Hardware an oder haben diese angekündigt.
Der RISC-V Befehlssatz wurde für eine Vielzahl von Anwendungsfällen entworfen. Er hat eine variable Datenwortbreite und ist erweiterbar, so dass jederzeit mehr Kodierungsbits hinzugefügt werden können. Er unterstützt drei Datenwortbreiten: 32, 64 und 128 Bit und eine Auswahl an Unterbefehlssätzen. Die Definitionen jedes Unterbefehlssatzes variieren geringfügig zwischen den drei Wortbreiten. Die Unterbefehlssätze unterstützen kompakte eingebettete Systeme, persönliche Rechner, Hochleistungsrechner mit Vektorprozessoren und Parallelrechner.
Der Befehlssatzraum für den auf 128 Bit gedehnten Befehlssatz wurde reserviert, weil 60 Jahre Industrieerfahrung gezeigt haben, dass die meisten nicht wieder gut zu machenden Fehler in der Gestaltung von Befehlssätzen durch fehlenden Speicheradressraum verursacht wurden. Noch im Jahr 2016 blieb der 128-Bit-Teil des Befehlssatzes absichtlich undefiniert, da bisher wenig Erfahrung mit solch großen Speichersystemen besteht. Es gibt Vorschläge, Instruktionen mit einer variablen Breite bis zu 864 Bit zu implementieren.[3]
Das Projekt begann 2010 an der University of California, Berkeley unter der Leitung von Krste Asanovic und David A. Patterson und wird bereits von Hard- und Softwareentwicklern weltweit mitentwickelt und gefördert.[4] Anders als andere akademische Entwürfe, die üblicherweise auf einfache Erläuterung optimiert sind (vgl. Mikrocodesimulator MikroSim), wurde der RISC-V-Befehlssatz für die praktische Anwendung in Rechnern entworfen. Er besitzt Eigenschaften, die die Rechnergeschwindigkeit erhöhen, aber trotzdem die Kosten und den Energieverbrauch senken. Dies schließt eine Load/Store-Architektur ein, sowie Bit-Muster, um die Multiplexer in einer CPU zu vereinfachen, vereinfachte Standard-basierte Gleitkommazahlen, einen architekturneutralen Entwurf und das Setzen des höchstwertigen Bits an eine festgelegte Position, um die Vorzeichenerweiterung zu beschleunigen. Vorzeichenerweiterung wird häufig als kritisch eingestuft. Im Jahre 2019 wurde die Version 2.2 des Userspace-ISA[5] und im Jahre 2021 die Version 1.12 des privilegierten ISA[6] festgelegt und ermöglichen es Software- und Hardwareherstellern, diesen zu nutzen oder zu implementieren. Eine Fehlersuch-Spezifikation ist in der Spezifikation der privilegierten ISA enthalten.
Der RISC-V-Befehlssatz steht in der Tradition der RISC-Prozessoren, die sich auf möglichst wenige, einfach zu dekodierende Maschinenbefehle konzentrieren. Dementsprechend hat der einfachste RISC-V-Befehlssatz (RV32I) nur 40 Befehle.
RISC-V hat in allen Varianten eine Wortgröße von 32 bit. Demnach sind alle regulären standardisierten Befehle 32 bit groß, und die kleinstmögliche Registergröße ist 32 bit. Für einige Befehle gibt es in der C-Erweiterung (siehe unten) alternative Kodierungen, die nur 16 bit (Halbwort) groß sind, allerdings dasselbe Verhalten aufweisen wie der entsprechende 32-bit-Befehl. Die Größe eines Maschinenbefehls kann an den untersten Bit des Befehls abgelesen werden, und Maschinenbefehle mit 64 und 128 bit Größe sind hier bereits vorgesehen. Ist die C-Erweiterung nicht implementiert, müssen Befehle an 4-Byte-Grenzen ausgerichtet sein, andernfalls können es auch 2-Byte-Grenzen sein (selbst für 32-bit-Befehle).
RISC-V ist eine Little-Endian-Architektur. Befehle werden immer in Little-Endian-Reihenfolge gelesen; daher auch die Kodierung der Befehlsgröße in den untersten Befehlsbits, die sich immer im ersten gelesenen Byte befinden. Falls die Implementierung dies unterstützt, kann nur für Datenzugriffe im Hauptspeicher auf Big-Endian umgeschaltet werden.
RISC-V ist nicht eine einzige Architektur, sondern eine ganze Familie an Architekturen, die modular aufeinander aufbauen. So gibt es die drei Grundarchitekturen namens RV32I, RV64I und RV128I, die entsprechend der Zahl im Namen eine Register- und Speicherbreite von 32, 64 bzw. 128 bit besitzen. Auch wenn streng genommen RV64I keine einfache Erweiterung von RV32I ist, werden alle existierenden Befehle mit neuer Bedeutung übernommen; der ADD-Befehl addiert beispielsweise nun statt zweier 32-bit Zahlen zwei 64-bit Zahlen. Die Grundarchitekturen enthalten entsprechend des „I“ im Namen nur Integer-Befehle, d. h. Befehle, die mit Ganzzahlen rechnen. Dazu kommen andere, fast immer benötigte Befehle wie bedingte und unbedingte Sprungbefehle, Speicherzugriffsbefehle und Software-Interrupt-Befehle. Alle weiteren Funktionalitäten sind in standardisierte Befehlssatzerweiterungen zusammengefasst, die jeweils eine 32-bit, 64-bit und 128-bit-Version besitzen. Wichtige Erweiterungen und ihre Namen sind:
Es ist explizit vorgesehen, dass proprietäre bzw. Drittanbieter-Erweiterungen für RISC-V verfasst werden, die einen mit X beginnenden Namen führen. Beispiele dafür sind XTheadBb, XTheadSync oder XVentanaCondOps.[7]
Verfügt eine RISC-V-Implementierung nun über eine bestimmte Sammlung an Erweiterungen, so kann diese entsprechend der Kurznamen kompakt bezeichnet werden, beispielsweise RV64IMCZicsr für einen Prozessor, der über die 64-bit-Basisarchitektur mit Ganzzahlmultiplikationen, komprimierten Befehlen und CSR-Unterstützung verfügt. Manche Erweiterungen hängen wiederum von anderen ab; so ist die Unterstützung von 64-bit-Gleitkommazahlen (D) nur gleichzeitig mit CSRs (Zicsr) und 32-bit-Gleitkommazahlen (F) möglich. Für eine CPU, die ein Endbenutzer-Betriebssystem ausführen kann, werden eine ganze Reihe an Erweiterungen benötigt, die unter der Pseudo-Erweiterung G (general purpose) zusammengefasst werden. RV64G bedeutet demnach eigentlich RV64IMAFDZicsr_Zifencei, also die Basisarchitektur inklusive sieben Erweiterungen.
RISC-V besitzt 32 Register, die ganze Zahlen enthalten. Die Basisarchitektur bestimmt deren Größe; so hat RV32 eben 32-bit-Register und RV64 64-bit-Register. Die Register werden mit den Architekturnamen x0 bis x31 bezeichnet. Dabei ist x0 ein besonderes Register, da es beim Lesen immer 0 enthält und alle Schreibvorgänge auf x0 ignoriert werden. Dies wird genutzt, um verschiedene Funktionen ohne zusätzliche Befehle möglich zu machen:
# Subtrahiert x6 von x0, d.h. negiert x6
sub x5, x0, x6
# Prüft, ob x0 kleiner als x13 ist, d.h. ob x13 größer als 0 ist
slt x2, x0, x13
# Speichert die Addition von 0 und x0 in x0; kanonisches NOP
addi x0, x0, 0
Viele dieser Funktionen sind in diversen Assembler-Pseudobefehlen verfügbar; für die drei Befehle oben wären es neg
, sgtz
bzw. nop
.
Rechenbefehle verfügen immer über drei Operanden: zwei Quellregister rs1
und rs2
und ein Zielregister rd
. Anders als bei anderen Architekturen ist das erste Quellregister nicht automatisch auch das Zielregister, wobei es natürlich möglich ist, dasselbe Register für Quelle und Ziel anzugeben. Befehle mit konstanten Operanden, sogenannte Immediate-Befehle, ersetzen rs2
durch eine Konstante, die im Befehl selbst enthalten ist. Einige Beispiele für Rechenbefehle:
# Addiert x0 (0) und 42 und speichert das Ergebnis in x7
# d.h. lädt die Konstante 42 in x7
addi x7, x0, 42
# Konstante 10 wird in x6 gespeichert
addi x6, x0, 10
# Subtrahiert x7 von x6 und speichert das Ergebnis in x5
sub x5, x6, x7
# Exklusives Oder mit Immediate
xori x4, x5, 0x1111
# Arithmetische Bitverschiebung nach rechts
sra x8, x4, x5
# Multipliziert x5 mit x4 und speichert das Ergebnis in x10
mul x10, x5, x4
Gewöhnliche Immediate-Befehle können aufgrund der Befehlskodierung ausschließlich 12-bit-Konstanten enthalten. Je nachdem, ob die Konstante vorzeichenlos oder vorzeichenbehaftet ist, bedeutet dies einen Wertebereich von 0 bis 4096 bzw. −2048 bis 2047. Um auch größere Konstanten kodieren zu können, gibt es den Befehl Load Upper Immediate (lui
). lui
lädt eine 32-bit-Konstante, deren obere 20 bit dem Immediate entstammen und deren untere 12 bit auf 0 gesetzt werden. Mittels einer darauffolgenden Addition kann so in zwei Befehlen jede 32-Bit-Zahl geladen werden:
# Die Zahl 987654321 (0x3ADE6'8B1) soll in Register x20 geladen werden.
# Lade in x20 die Konstante 0x3ADE6'000,
# Das 20-bit-Immediate-Argument wird in Bit 31...12 geschrieben, Bit 11...0 werden genullt
lui x20, 0x3ADE6
# Setzen der unteren 12 bit
addi x20, x20, 0x8B1
# Verbreitete Assembler unterstützen den Makrobefehl li (load immediate)
# welcher je nach Konstante 1 oder 2 Befehle erzeugt:
li x20, 0x3ADE68B1
Der Befehl Add Upper Immediate to Program Counter (auipc
) addiert einen solchen 20-Bit-Immediate stattdessen zum aktuellen Programmzähler (Program Counter), womit effizient Speicheradressen in der Nähe des Programmcodes abgerufen werden können und der Code positionsunabhängig wird.
RISC-V hat als Load/Store-Architektur keine Befehle, die direkt auf Daten im Speicher Rechenoperationen durchführen können. Eine Ausnahme hiervon bilden die atomaren Befehle aus der A-Erweiterung, die solche Funktionalität zur Prozessorsynchronisierung benötigen (amoadd
, amoor
, amoswap
etc.). Für reguläre Speicherzugriffe ist nur ein einfaches Laden oder Speichern vom/zum Hauptspeicher möglich, und der Addressierungsmodus ist immer Register+Konstante. Beispielsweise kann das Register die Startadresse einer Struktur enthalten und die Konstante den Offset eines Felds in der Struktur.
# Lade Byte von Adresse 0x40
lb x11, 0x40(x0)
# Lade erstes Wort auf dem Stack (x2 ist der Stack Pointer)
lw x12, 4(x2)
# Lade Halbwort (16 bit) ohne Vorzeichenerweiterung
lhu x13, 2(x2)
# Speichere Doppelwort (nur RV64 und RV128)
sd x13, 8(x2)
# Speichere Wort ohne Vorzeichenerweiterung (nur RV64 und RV128)
swu x12, 0(x2)
Speicherzugriffe müssen ausgerichtet sein, z. B. Wortzugriffe auf Vielfache von 4 Byte und Doppelwortzugriffe auf 8 Byte. Eine Implementierung kann auch unausgerichtete Speicherzugriffe unterstützen, dies ist jedoch in der Regel nicht der Fall und wird eventuell in der Firmware emuliert (fast trap and emulate).
RISC-V besitzt anders als die meisten heutzutage verbreiteten Architekturen kein Statusregister und keine Flags. Kontrollflussentscheidungen werden immer auf der Basis eines konkreten Vergleichs durchgeführt, zum Beispiel:
# Springe falls x4 < x5 (ganze Zahlen)
blt x4, x5, label1
# Springe falls x7 >= x9 (natürliche Zahlen)
bgeu x7, x9, label2
# Springe falls x1 = 0 (Pseudobefehl beqz)
beq x1, x0, label3
Das Sprungziel wird im Maschinenbefehl als Offset vom aktuellen Befehl angegeben und kann bis zu ±4KiB betragen.
Für bedingungslose Sprünge, Prozeduraufruf und Rückkehr aus einer Prozedur dienen Jump And Link (jal
) und Jump And Link Register (jalr
). jal
verwendet ein Offset wie die bedingten Branch-Befehle, wobei dank 20-bit-Offset jetzt Sprünge ±1MiB möglich sind. jalr
benutzt ein kleineres Offset addiert zu einem Register und kann somit auf den gesamten Speicherbereich springen. Beide Befehle speichern die Adresse des folgenden Befehls im Zielregister, was später einen Rücksprung ermöglicht.
# Sprung ohne Speichern der Rücksprungadresse (Pseudobefehl j)
jal x0, label1
# Rücksprungadresse wird im Return-Address-Register x1 gespeichert (Pseudobefehl call)
jal x1, my_procedure
# Sprung zur Return-Adresse aus x1 (Pseudobefehl ret)
jalr x0, x1, 0
RISC-V unterstützt mit den F-, D-, und Q-Erweiterungen Gleitkommazahlen nach dem IEEE 754-2008-Standard. 32 separate Register für Gleitkommazahlen sind verfügbar, f0-f31 genannt, wobei das Register f0 keine Sonderstellung wie x0 einnimmt. Je nach konkreter Erweiterung haben die Register eine Größe von 32, 64 oder 128 bit, und Gleitkommazahlen kleinerer Größe (bspw. 32-bit-Gleitkommazahlen auf einer Implementierung mit D-Unterstützung) werden mittels NaN-Packing „eingebettet“.
Gleitkommaoperationen haben analog zu den Ganzzahloperationen drei Operanden (zwei Quellregister und ein Zielregister). Ein Quadratwurzelbefehl existiert (fsqrt
), aber beispielsweise kein Sinus oder Kosinus. Es existieren direkte Speicherzugriffsbefehle, die Gleitkommaregister laden und speichern können. Es können sowohl Ganzzahlen in Gleitkommazahlen umgewandelt werden und zurück (fcvt
), als auch die IEEE-754-Darstellung einer Kommazahl direkt aus einem Ganzzahlregister geladen oder in ein solches gespeichert werden (fmv
). Mittels der Sign-Injection-Befehle (fsgnj
, fsgnjx
, fsgnjn
), die den Betrag des ersten Quellregisters und das Vorzeichen des zweiten Quellregisters kombinieren, können zusätzlich die Operationen Negation, Betrag und Register-Transfer (fmv
) implementiert werden.
In den Basiserweiterungen F, D, und Q sind Fused-Multiply-Add-Befehle enthalten (fmadd
, fmsub
, fnmadd
, fnmsub
), die als einzige Standardbefehle überhaupt vier Operanden (drei Quellregister) enthalten. Diese benötigen einen wesentlichen Anteil des 32-bit-Befehlsraums, sorgen aber in mathematischen Operationen und Multimediaanwendungen für einen deutlichen Geschwindigkeitsgewinn[8].
# Ausschnitt aus einer asinh-Implementierung
# Programmkonstante laden
auipc x12,0xfffbf
fld f11,-1154(x12)
# Diese Befehle nutzen alle dynamische Rundung
fmadd.d f5,f4,f5,f6
fmadd.d f5,f4,f5,f7
fmadd.d f5,f4,f5,f10
fmadd.d f5,f4,f5,f11
fld f6,-426(x10)
fmul.d f4,f4,f5
fmul.d f4,f3,f4
fmadd.d f2,f3,f2,f4
fmul.d f2,f2,f6
IEEE-754-Exceptions lösen keine Interrupts aus (was vom Standard auch erlaubt ist). Stattdessen dient das fflags
(Gleitkomma-Flags)-Kontrollregister zur Auflistung aller aufgetretenen Gleitkomma-Fehler.
Der Rundungsmodus kann in den meisten Befehlen fest angegeben werden und wird ansonsten dem frm
(Gleitkomma-Rundungsmodus)-Kontrollregister entnommen:
Rundungsmodus | Mnemonic | Bedeutung |
---|---|---|
000 | RNE | Runde zur nächstgelegenen Zahl, bevorzuge gerade Zahlen |
001 | RTZ | Runde in Richtung ±0 |
010 | RDN | Runde ab in Richtung −∞ |
011 | RUP | Runde auf in Richtung +∞ |
100 | RMM | Runde zur nächstgelegenen Zahl, bevorzuge größeren Betrag |
111 | DYN | nutze frm -Kontrollregister für Rundungsmodus |
Um das Verhalten des Prozessors und verschiedener Befehle zu steuern, verfügt ein RISC-V-Prozessor mit der Zicsr-Erweiterung über bis zu 4096 sogenannter Control and Status Register, d. h. Kontroll- und Statusregister, abgekürzt CSRs. Die CSRs werden mit eigenen Befehlen wie csrrw
und csrrci
modifiziert, die in der Regel gleichzeitig ein CSR lesen und schreiben, außer es wird x0 als Operand genutzt. Abhängig vom Prozessormodus und der Implementierung sind manche CSRs nur lesbar, oder Schreibzugriffe werden ignoriert. Wichtige CSRs sind beispielsweise:
fflags
) und Rundungsmodi (frm
)cycle
), Monotoner Zeitzähler beliebiger Auflösung (time
), abgearbeitete Befehle (instret
) und 29 weitere Zähler mit unspezifizierter FunktionDer Großteil der CSRs wird für Systemfunktionalitäten benötigt und ist daher in üblichen Benutzeranwendungen nicht verfügbar. Dazu gehören beispielsweise:
sstatus
, sie
, stvec
, ...)sepc
/mepc
, scause
/mcause
, stval
/mtval
, ...)pmpcfg0
-pmpcfg15
, pmpaddr0
-pmpaddr63
)misa
)Die ABI für RISC-V wird, anders als bei vielen Architekturen, gemeinsam mit der ISA spezifiziert und standardisiert.[9] Je nach Basisarchitektur und genauer Prozeduraufrufkonvention, besonders zur Behandlung von Gleitkommaparametern, gibt es verschiedene inkompatible ABIs, die wie die Architekturen mit Kürzeln wie LP64D, ILP32 oder ILP32E bezeichnet werden. Teil der standardisierten ABI ist auch die Spezifikation zur Verwendung des ELF-Binärformats für RISC-V.
Die ABI weist einigen Registern besondere Bedeutungen zu und teilt die übrigen Register in die Kategorien Saved, Argument und Temporary ein. Jedes Register, ob Ganzzahl- oder Gleitkommaregister, erhält entsprechend einen ABI-Namen, der die Assemblerprogrammierung vereinfacht.
Register | ABI- Name(n) |
Bezeichnung | Erklärung |
---|---|---|---|
x0 | zero | Zero | Konstantes Nullregister (Lesen: Wert 0, Schreiben: kein Effekt) |
x1 | ra | Return address | Rücksprungadresse; wird in Pseudobefehlen wie ret und call implizit genutzt. |
x2 | sp | Stack pointer | Stapelzeiger. Einige Erweiterungen wie C besitzen spezialisierte Befehle hierfür. |
x3 | gp | Global pointer | Zeiger auf die Liste globaler Programmsymbole. |
x4 | tp | Thread pointer | Zeiger auf den TLB des aktuellen Programmthreads, siehe Thread-local storage. |
x8 | fp | Frame pointer | Framezeiger, zeigt auf die Startadresse des aktuellen Stackframes. Optional; entspricht auch s0. |
x5…7, x28…31 | t0…6 | Temporary registers | Register für temporäre Daten, die beim Prozeduraufruf nicht erhalten bleiben müssen. |
x8…9, x18…27 | s0…11 | Callee-saved registers | Register, die von aufgerufenen Prozeduren gesichert werden, falls sie diese benötigen. |
x10…17 | a0…7 | Argument registers | Register für die ersten 8 Prozedurargumente und Rückgabewerte. |
f0…7, f28…31 | ft0…11 | Floating-point Temporary registers | Temporäre Register für Gleitkommazahlen. |
f8…9, f18…27 | fs0…11 | Floating-point Callee-saved registers | Gesicherte Register für Gleitkommazahlen. |
f10…17 | fa0…7 | Floating-point Argument registers | Register für die ersten 8 Gleitkomma-Argumente und -Rückgabewerte von Prozeduren. |
Bei einem Prozeduraufruf werden nur die gesicherten bzw. unveränderlichen Register wie s0-s11 oder gp erhalten. So viele Argumente wie möglich werden in den Argumentregistern übergeben, weitere Argumente kommen auf den Stack. Rückgabewerte werden genauso wie Argumente übergeben.
Prozeduraufrufe (mit Pseudobefehlen ret
und call
) interagieren nicht ohne weiteres mit dem Stack, was die manuelle Sicherung der Rücksprungadresse spätestens direkt vor einem weiteren Prozeduraufruf erfordert. In der Praxis werden Register nach aufsteigender Nummer auf dem Stack gesichert, sodass die Rücksprungadresse auf dem Stack ganz unten liegt. Führt eine Prozedur allerdings keinen weiteren Prozeduraufruf auf, so erübrigt sich auch die Sicherung der Rücksprungadresse.
Ein RISC-V-Stack wächst „nach unten“ (Richtung absteigender Adressen) und der Stapelzeiger zeigt immer auf den obersten in Verwendung befindlichen Speicher.
# Beginn der asinh-Prozedur von oben
# Stack um zwei Doppelworte vergrößern...
addi x2, x2, -16
# ... damit zwei Register gesichert werden können.
sd x1, 8(x2) # Rücksprungadresse (diese Prozedur ruft noch andere Prozeduren auf)
sd x8, 0(x2) # Frame Pointer des Aufrufers
# Neuen Frame Pointer einrichten (entsprechend der Stackadresse beim Prozedureintritt)
addi x8, x2, 16
# ...
# Ende von asinh
# f10 (=fa0) enthält den Rückgabewert
fdiv.d f10, f0, f1
# Rücksprungadresse und Frame Pointer wiederherstellen
ld x1, 8(x2)
ld x8, 0(x2)
# Stack verkleinern und damit wiederherstellen
addi x2, x2, 16
# Rücksprung (ret)
jalr x0, x1, 0
Aspekte von RISC-V, die ein laufendes System und seine Verwaltung betreffen, werden in der privilegierten Spezifikation (genannt Band II) behandelt.[6] Wie der Name „privilegiert“ besagt, ist diese besonders für Entwickler privilegierter Anwendungen (z. B. Betriebssysteme) oder Implementierer relevant, da Benutzeranwendungen selten mit diesen Aspekten interagieren.
RISC-V besitzt hauptsächlich drei Privilegienstufen, meist einfach Modes genannt. Nur M-Mode muss in jedem System vorhanden sein; andere Modi sind normale Architekturerweiterungen, die beispielsweise über misa
erkannt werden können.
Name (Erweiterung) |
Bezeichnung | Vorgesehen für… |
---|---|---|
U | User/Application | Benutzeranwendungen oder Software in sicheren Embedded-Systemen |
S | Supervisor | Betriebssysteme |
M | Machine | Firmware oder Embedded-Software |
Der Debug-Modus einer debugbaren Implementierung ist streng genommen ein eigener Privilegienmodus, der Zugriff auf weitere CSRs und Speicherbereiche hat, die aus dem M-Mode nicht benutzt werden können. Außerdem wird unter der Hypervisor-Erweiterung (siehe unten) der S-Mode in mehrere Untermodi unterteilt.
Jeder Modus kontrolliert, auf welche Systemfunktionalitäten ein darüberliegender Modus Zugriff hat. M-Mode ist für die Firmware einer Implementierung gedacht, die nicht vom Betriebssystem geändert werden kann (vergleiche BIOS). M-Mode hat Zugriff auf alle Speicherbereiche, CSRs und Hardwarefunktionalitäten, auch solche, die eigentlich für höhere Modi gedacht sind. S-Mode wird von Betriebssystemen genutzt und hat Zugriff auf einen Großteil der Systemfunktionalitäten, wie die Konfiguration von virtuellem Speicher und Speicherschutzfunktionen. M-Mode kann zudem weitere Aufgaben, wie die Behandlung von Traps, an den S-Mode delegieren. Benutzerprogramme im U-Mode können per Design keinen Zugriff auf solche Funktionen haben.
RISC-V unterstützt mehrere Arten des virtuellen Speichers, die je nach Implementierung konstant oder umschaltbar sind. Ungeachtet des virtuellen Speichermodus sind Speicherseiten 4KiB groß und die unteren 12 bit einer Adresse beschreiben den Seitenoffset.
Für RV32 gibt es nur Sv32, welches eine zweistufige Seitentabelle mit je 10 Bit pro Tabellennummer verwendet. Dabei kann bereits ein Level-1-PTE ein Blatteintrag ohne untergeordnete Seitentabelle sein; in diesem Fall beschreibt der Eintrag eine 4-MiB-Megapage.
Für RV64 gibt es Sv39, Sv48 und Sv57, die entsprechend der Zahl im Namen eine bestimmte virtuelle Addressgröße haben. Bereits 39 bit (512 GiB) sind für viele heutige Anwendungen ausreichend. Alle drei virtuelle Speichermodi benutzen 9 bit pro Tabellennummer und haben 3-, 4- bzw. 5-stufige Tabellen. Die PTEs unterscheiden sich nur in Details, und auch hier gibt es die Möglichkeit, durch Blatteinträge in höherstufigen Seitentabellen Megapages (2 MiB), Gigapages (1 GiB), Terapages (512 GiB) und Petapages (256 TiB) zu erzeugen.
Speicherschutz kann auf zwei Arten erreicht werden. Zum einen mittels der 64 physischen Speicherattribute (Physical Memory Attributes, PMP), die in den pmp
-CSRs festgelegt sind und eventuell nicht veränderbar sind (z. B. Nur-Lese-Attribut für ROM-Regionen). Zum anderen verfügt jede virtuelle Speicherregion über (im S-Mode) konfigurierbaren Speicherschutz, der während der Adressübersetzung geprüft wird. RISC-V definiert die Zugriffsarten Lesen, Schreiben und Ausführen, wobei das Ausführen eines Speicherworts nicht als Lesezugriff gilt. Code kann also als nicht lesbar konfiguriert werden, was einen Zugriff mit Speicherzugriffsbefehlen verhindert. Außerdem kann eine Speicherregion als vom U-Mode nicht zugreifbar definiert werden.
Um Funktionalität des umgebenden Systems abrufen zu können, besitzt RISC-V ein verallgemeinertes Systemaufruf-Verfahren, das Environment Calls, d. h. Umgebungsaufrufe, genannt wird. Der dafür zuständige Befehl ecall
(Teil der I-Basisarchitektur) kann in jedem Privilegienmodus genutzt werden, um ein Trap (d. h. Softwareinterrupt) in den nächsthöheren Modus auszulösen. Dieser kann die Anfrage dann behandeln und mittels mret
oder sret
die Kontrolle an den anfragenden Modus zurückgeben. Welche Funktionen verfügbar sind und wie Argumente übergeben werden, definiert die ABI (für U-Mode nach S-Mode, d. h. Systemaufruf) oder SBI (Supervisor Binary Interface für S-Mode nach M-Mode, d. h. Firmwareinterface). Üblicherweise ähnelt die Aufrufkonvention der normalen Prozeduraufrufkonvention, z. B. werden Argumente in den Argumentregistern a0-a7 übergeben.
Die SBI ist standardisiert[10] und definiert eine Reihe an Funktionen und Erweiterungen, deren Vorhandensein von S-Mode-Software abgefragt werden und dann verwendet werden kann. Dabei werden Register a7 für die ID der Erweiterung und Register a6 für die Funktion innerhalb der Erweiterung genutzt. Beispielsweise kann mit Erweiterung 16 (verpflichtende Basiserweiterung) und Funktion 0 die implementierte SBI-Spezifikationsnummer abgerufen werden, oder mit Erweiterung 4442434E16 und Funktion 2 ein Textzeichen auf der Debugging-Konsole ausgegeben werden.[11]
Zur Unterstützung der Virtualisierung bietet RISC-V die Hypervisor-Erweiterung, die S-Mode in einen HS-Mode (hypervisor extended supervisor) und VS-Mode (virtual supervisor) aufteilt. HS-Mode erhält Zugriff auf eine Reihe an speziellen CSRs und kann zudem die Supervisor-CSRs des VS-Mode separat konfigurieren. Ein Umgebungsaufruf aus dem VS-Mode wird nun vom HS-Mode (statt M-Mode) behandelt, sodass der Hypervisor z. B. eine völlig andere Firmware und virtuelle Geräte emulieren kann, als eigentlich hardwareseitig vorhanden ist. Auch können Traps an den VS-Mode delegiert werden, beispielsweise um direkten Zugriff auf physische Hardware zu erlauben. VS-Mode besitzt seinen eigenen virtuellen Speicher, der in zwei Stufen übersetzt wird: zunächst von virtuellen Gastadressen in physische Gastadressen (entsprechend normalen virtuellen Adressen), und dann von physischen Gastadressen in physische Adressen. Mittels spezieller Hypervisor-Befehle (hlv
, hlvx
etc.) kann der Hypervisor (oder ein Benutzerprogramm im HU-Mode) wie VS-Mode mit virtuellen Gastadressen Speicherzugriffe ausführen.
RISC-V ist ein offener Standard, welcher eine Befehlssatzarchitektur spezifiziert, aber weder eine Mikroarchitektur noch ein Lizenzmodell vorgibt. Aus diesem Grund wurden sowohl RISC-V Kerne mit kommerzieller Lizenz als auch mit Open-Source-Lizenz entwickelt. Die RISC-V-Stiftung pflegt eine Liste aller RISC-V-CPU- und -SoC-Implementierungen.[13]
Folgende Betriebssysteme wurden, unter anderem, auf die RISC-V-Prozessorarchitektur portiert:
Außerdem können Programme mithilfe von verschiedenen Kompilern wie z. B. der GNU Compiler Collection und LLVM zu RISC-V-Maschinencode kompiliert werden.
RISC-V ist als variable Befehlssatzarchitektur interessant für nationale- sowie supranationale Förderung als Reaktion auf die Chipkrise, beispielsweise um effizientere Mikroprozessoren zu entwickeln. Im Europäischen Chip-Gesetz wird RISC-V als eine vielversprechende Architektur angesehen, um Prozessoren mit niedrigem Stromverbrauch zu entwickeln und den Versorgungsengpässen bei Halbleitern entgegenzuwirken, indem die Produktion in Europa gesteigert wird.[31][32]
In den USA gibt es ebenfalls Bestrebungen, die Entwicklung energieeffizienter Prozessoren mit Hilfe des CHIPS and Science Act zu forcieren.[33]
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.