Kapitel 9 - Software Interrupt (SWI / SVC)

Startseite · Kap. 8 Regelungen · 9 Software Interrupt · → Kap. 10 Leitungscodes & CRC Verwandt: ARM-Architektur (Modi, CPSR) · Kap. 6 Interrupts Quellen: [Q: SI] ES-10-SI Softwareinterrupt · [Q: ZF §10/§10a]


Inhalt

  1. Konzept & Zweck
  2. Warum privilegierter Modus?
  3. Ablauf (Hardware)
  4. SWI-Handler (Software)
  5. Cortex-M3: SVC
  6. Prüfungsrelevanz

1. Konzept & Zweck

Ein Software Interrupt ist eine benutzerdefinierte, synchrone Programmunterbrechung, um vom User Mode in den privilegierten (Supervisor) Mode zu gelangen.

  • Dient als Schnittstelle Anwendung ↔ Betriebssystem (System Calls, z. B. putchar, getchar).
  • Im privilegierten Mode laufen privilegierte Operationen, die im User Mode verboten sind. Dort läuft typischerweise das Betriebssystem → HW-Schutz vor Anwendungen.
  • synchron (im Gegensatz zum HW-Interrupt): tritt genau beim SWI/SVC-Befehl auf, nicht asynchron.

2. Warum privilegierter Modus?

Im User Mode nicht erlaubt / geschützt:

  • Zugriff auf den Speicherbereich der eingeblendeten Peripherie (I/O).
  • Schreibzugriff auf Teile des Prozessor-Statusworts (CPSR).
  • Moduswechsel der CPU oder Interrupts sperren.
  • Beschreiben der Vektortabelle.
  • Zugriff auf MPU/MMU (Memory Protection/Management Unit - Speicherschutz/virtuelle Adressen).

Nicht alle MC unterstützen einen SWI: Cortex-M0+ hat keinen dedizierten SWI-Maschinenbefehl.

3. Ablauf (Hardware-seitig, ARM7TDMI)

Befehl: SWI #<Nummer> (Syntax swi{<cond>} <Nummer>). Beim Ausführen macht die CPU automatisch:

  1. Status sichern: CPSR → SPSR_SVC (Flags + alter Modus bleiben erhalten).
  2. Moduswechsel in Supervisor ModeSP_svc und LR_svc werden aktiv.
  3. Interrupts sperren: IRQ-Disable-Bit (I) im CPSR gesetzt → Handler wird nicht sofort unterbrochen.
  4. Rücksprungadresse sichern: Adresse des Befehls nach dem SWI → LR_svc (= PC − 4).
  5. Sprung zum Vektor: PC → feste Adresse 0x08 (SWI-Exception-Vector).

Befehlsformat ARM7: obere 4 Bit cond, dann 1111, dann 24-Bit-Immediate = SWI-Nummer.

4. SWI-Handler (Software-seitig)

Der Handler (ab 0x08) muss die SWI-Nummer extrahieren - sie steht nicht in einem Register, sondern im Maschinencode des Befehls selbst:

  1. Befehl an Adresse [LR − 4] laden (der SWI-Befehl).
  2. Obere 8 Bit (Opcode) mit BIC ... #0xff000000 ausmaskieren → verbleibende 24 Bit = SWI-Nummer.
  3. Anhand der Nummer verzweigen (Sprungtabelle / switch).
  4. Rücksprung: SPSR → CPSR, LR → PC (User Mode wiederhergestellt).

Assembler-Handler:

SWIHandler:
    stmfd sp!, {lr}              @ Rücksprungadresse retten
    ldr   ip, [lr, #-4]          @ SWI-Befehlscode laden
    bic   ip, ip, #0xff000000    @ obere 8 Bit ausmaskieren → SWI-Nummer
    ldr   lr, =SWIJumpTable
    ldr   ip, [lr, ip, LSL #2]   @ Funktionsadresse aus Sprungtabelle
    mov   lr, pc
    mov   pc, ip                 @ indirekter Aufruf
    ldmfd sp!, {pc}^             @ Rücksprung + CPSR restaurieren
SWIJumpTable:
    .word putchar
    .word getchar
    .word init_ser

C-Handler:

void SWIHandler() __attribute__((interrupt("SWI")));
register int *reg_14 asm("r14");         // Link Register
void SWIHandler() {
    switch (*(reg_14 - 1) & 0x00FFFFFF) { // obere 8 Bit maskieren
        case 0: function0(); break;
        case 1: function1(); break;
        case 2: function2(); break;
    }
}
// Aufruf:  asm("swi 0");

5. Cortex-M3 - SVC

  • Befehl: SVC #<Nummer> (statt SWI). Vektor über die Vektortabelle (SVCall-Exception).
  • SVC-Nummer ermitteln: Der Handler holt den gestackten PC (svc_args[6]), liest das Byte direkt vor dem PC → das ist die SVC-Nummer (2-Byte-SVC-Befehl):
unsigned int stacked_pc = svc_args[6];
unsigned char svc_number = ((unsigned char*)stacked_pc)[-2];
  • Modi (Wiederholung ARM-Architektur): Thread (priv./unpriv., MSP/PSP) ↔ Handler (immer privileged, MSP). Eintritt über Interrupt/SVC/Fault.
  • Beispiel Linux: SWI-Handler im Kernel unter arch/arm/kernel/entry-common.S.

Prüfungsrelevanz

  • Zweck: User → Supervisor Mode für privilegierte Operationen / System Calls.
  • synchron (vs. HW-Interrupt asynchron).
  • SWI-Nummer extrahieren: aus [LR−4], obere 8 Bit maskieren (BIC #0xff000000).
  • Vektoradresse 0x08 (ARM7); LR_svc = PC−4; CPSR→SPSR_SVC; IRQ gesperrt.
  • SWI (ARM7) vs. SVC (Cortex-M3); Cortex-M0+ hat keinen.

Typische Fehler: SWI für asynchron halten · SWI-Nummer in einem Register vermuten (sie steht im Opcode) · falsche Maske (0xff000000 obere 8 Bit).

Kap. 8 Regelungen · → Kap. 10 Leitungscodes & CRC