Hallo,
>Was ist ein Coprozessor im Sinne einer ARM-CPU?
Das ist typisch ARM und wieder völlig missverständlich.
Es handelt sich hier nicht um eine eigene CPU sondern um eine
Erweiterung der ARM v6 CPU.
Das Coprozessor-Infterface stellt ein Register-Interface zum Ansrpechen
der verschiedenen Subsysteme, die nicht direkt in der CPU eingebaut
sind, bereit. Dazu zählen z.B. Memory-Protection, Interrupt Controller,
Cache, ect. Dabei hat jedes Subsystem eine eigene 'Nummer'.
Welches Register sich hinter der 'Codierung' verbrigt muß man sich aus
der ARM Doku zusammen suchen.
Jetzt zum ASM-Befehl:
>asm volatile("mcr p15, 0, %[addr], c12, c0, 0" : : [addr] "r"
(&interrupt_vectors));
mcr (move to copro register):
P15 ist die Nummer des Coprozessors (in deinem Fall wohl der Interrupt
Controller).
C12, C0 und die beiden 0 definieren das anzusprechende Register im
Copro.
Für den Compiler ist asm volatile(...) wie ein Funktionsaufruf. Dieser
kann Parameter und einen Return Wert haben. Der Compiler versteht den
ASM-Code aber nicht. Daher muß ihm am Ende der ASM-Sequenz durch eine
Liste mitgeteilt werden, welche Register die Eingangsparameter
beinhalten und wo der Return-Wert abgelegt werden soll.
Die Syntax ist dabei
asm volatile("string mit asm instruktionen": Ausgangsreg: Liste mit
Eingangswerten.
Dabei wird auch noch mit symbolischen Ersetzungen gearbeitet. %[addr]
heißt, genau an dieser Stelle soll das "Symbol" addr aus der Liste
genommen werden.
In der Liste sagt man, dass [addr] ein "r"-register ist das vorher mit
dem C-Symbol &interrupt_vectors zu laden ist.
In Pseudo C-Code würde der Befehl so aussehen:
uint32 r = &interrupt_vectors;
asm_func(r)
void asm_func(uint8 r)
{
*(Copro_x_Reg_y) = r;
}
Hier hilft ein Blick in das ARM-Compiler Manual.
(GCC macht das anders...)
Hoffe, das war einigermaßen richtig und verständlich.