Eccezioni su MPC555

Quali sono le informazioni che bisogna conoscere per gestire correttamente una ISR in un MPC555? Questo articolo fornirà elementi utili per gestire un'eccezione su MPC555.

Il componente siglato come MPC555 appartiene alla famiglia Powerpc™ e contiene al suo interno timers e altre periferiche che, se opportunamente programmate, possono generare interrupts. L’architettura è definita in tre livelli che corrispondono a tre ambienti di programmazione. Questa stratificazione dell’architettura fornisce una maggiore flessibilità al sistema, consentendo un maggior grado di compatibilità software tra un’ampia gamma di implementazioni. I tre livelli sono definiti in questo modo:

User Instruction Set Architecture (UISA): UISA definisce il livello  di architettura a cui il software user-level deve essere conforme. UISA definisce così il set base di istruzioni per l’utente, i registri  a cui può accedere, le convenzioni per la memorizzazione degli operandi in virgola mobile ed il modello delle eccezioni visto dall’utente. Le risorse definite a questo livello possono essere accedute in modalità user.

Virtual Environment Architecture (VEA): a questo livello sono definite delle funzioni addizionali che esulano dai requirement software del livello utente. VEA descrive il modello della memoria in un ambiente in cui molti dispositivi vi possono accedere e definisce i  servizi time base dalla prospettiva dell’utente. Le risorse definite a questo livello possono essere accedute in modalità user.

Operating Environment Architecture (OEA): definisce le risorse di livello supervisore tipicamente richieste dal sistema operativo. Infatti, in questo livello trovano posto il modello di gestione della memoria,  i registri supervisor  level, i requisiti di sincronizzazione ed il modello delle eccezioni. Le risorse definite a questo livello possono essere accedute esclusivamente in modalità supervisor.

PowerPC core interrupt

La figura 1 mostra l’architettura interna dell’interrupt controller, come si vede il componente ha un solo segnale di interrupt in ingresso.

Figura 1: interrupt controller.

Figura 1: interrupt controller.

Questo interrupt viene abilitato o meno agendo sul bit EE (External Enable) del reutilizzare l’istruzione assembler mtspr, nel seguente modo:

mtspr EID, r0 ;
Set RI bit = 1 and EE bit = 0 in MSR

Eccezioni

La porzione OEA dell’architettura PowerPC™ definisce il  meccanismo con cui il processore implementa le eccezioni. Il  meccanismo delle eccezioni consente al processore di passare in modalità supervisore, aumentando  il livello di privilegio, a fronte di un evento quale un segnale esterno, un errore o del verificarsi di una condizione anomala durante l’esecuzione di un’istruzione. Quando viene sollevata un’eccezione lo stato del gistro machine state register (MSR): questo bit abilita anche l’eccezione chiamata decrementer.  Il decrementer  è un particolare interrupt (evento asincrono) che può essere generato periodicamente: di solito viene utilizzato come timer di sistema (tick timer). Ci sono, poi, tre registri speciali (EIE, EID e NRI) utilizzati per modificare direttamente i  bits RI e EE del registro MSR. Infatti, qualsiasi scrittura a questi registri causa la modifica conseguente dei bit corrispondenti nell’MSR. Questi registri speciali non sono accessibili da un programma scritto in C, ma dobbiamo la macchina viene salvato in appositi registri ed il processore inizia la sua esecuzione da un indirizzo predeterminato per ogni tipo di eccezione –exception vector. L’elaborazione di un’eccezione viene eseguita in modalità supervisore. Ogni tipo di eccezione ha un suo offset predeterminato che sommato all’indirizzo base dell’exception vector fornisce l’indirizzo della prima istruzione da eseguire. L’architettura PowerPC richiede che le eccezioni vengano gestiste in ordine col programma, quindi, nonostante particolari implementazioni possano riconoscere le condizioni di eccezione out-of-order, queste devono essere gestite strettamente in ordine, rispettando il flusso del le istruzioni. Quando un’eccezione causata da un’istruzione è riconosciuta, tutte le istruzioni non eseguite che sono precedenti a questa devono essere completate prima che l’eccezione sia gestita. L’elaborazione di un’eccezione passa attraverso tre fasi:

1- Riconoscimento: si verifica quando la condizione di eccezione è identificata dal processore.

2- Accettazione: un’eccezione si dice accettata quando il controllo dell’istruzione in esecuzione passa al suo handler, cioè viene salvato il contesto e l’istruzione che si trova all’appropriato offset dell’exception vector viene “fetchata”.

3- Gestione: l’eccezione viene gestita dal suo handler agganciato dall’appropriato exception vector.

Classi di Eccezioni

Tutte le eccezioni possono essere classificate come sincrone ed asincrone. Le eccezioni asincrone sono causate da eventi esterni al processore, quelle sincrone dalle istruzioni. La tabella 1 mostra le possibili eccezioni previste in questo dispositivo.

Tabella 1 –Exception Vector Table Alternatives

Tabella 1 –Exception Vector Table Alternatives

Quando viene riconosciuta un’eccezione l’invio delle istruzioni alle unità di esecuzione viene bloccato e, successivamente, si esegue la seguente sincronizzazione:
il  meccanismo delle eccezioni attende che tutte le istruzioni precedenti nel flusso originale di esecuzione siano completate, almeno fino ad un punto in cui non possono più provocare eccezioni. In questo modo il processore si assicura che tutte le istruzioni precedenti vengano completate nel contesto corrente. Il  meccanismo delle eccezioni implementato in hardware ed in software è responsabile del salvataggio e ripristino dello stato del processore.

Struttura di una ISR

La struttura di una ISR  è costituita da un’insieme di operazioni riassunti nei passi successivi. Come primo passo viene controllato e gestito lo stato della macchina, infatti una volta che l’eccezione viene rilevata le esecuzioni correnti devono essere concluse, la CPU salva l’indirizzo della prossima istruzione,  il contenuto del registro MSR (dal bit 16 a 31) in SRR0:1 e, infine, modifica il registro MSR.

In sostanza,  il processore  utilizza i registri SRR0-SRR1 per salvare il program counter e il contenuto di MSR: servono per ripristinare il normale flusso al rientro dalla gestione dell’interrupt (hander). In conclusione del primo passo, il puntatore alle istruzioni del PowerPc cede il controllo all’handler situato all’indirizzo contenuto dell’exception vector. Il secondo passo, in realtà, è formato da diversi punti svolti dal software.

➤ Viene salvato il  contesto di SRR0 e SRR1, per esempio:

stwu sp, -80 (sp) ; Create stack frame

and store back chain stw r3, 36 (sp)         ; Save a working

register in stack frame for use as a

; scratch register mfsrr0 r3               ; Copy SRR0 to r3 stw r3, 12 (sp)      ; Save SRR0 value

on stack

mfsrr1 r3                ; Copy SRR1 to r3 stw r3, 16 (sp)  ; Save SRR1 value

on stack

➤ Setta il bit identificato come recoverable e, eventualmente, altre informazioni utili per il contesto.
mtspr EID, r3; Set MSR[RI] to indicate recoverable condition. Qualsiasi altro registro può essere salvato, per esempio, con questa istruzione:

stw r4, 40 (sp) ; Store gpr4 on stack

I registri speciali utilizzano  due istruzioni, come SRR0 e SRR1. Per esempio:

mfxer r3                 ; Copy special purpose register XER to gpr3
stw r3, 20 (sp)       ; Save XER value to stack

Per ottimizzare il  lavoro di salvataggio sullo stack, possono essere utilizzate le istruzioni lswi o stswi.

➤ Si determina a questo punto la ragione dell’eccezione.
Per farlo dobbiamo controllare l’interrupt code nello USIU interrupt controller del registro SIVEC ed eseguire  il gestore associato. Una volta che l’indirizzo della ISR è caricato nel registro dobbiamo fare solo un salto a questo: come? Con blrl. Infatti l’architettura permette di fare delle operazioni di salto, branch, utilizzando il registro CTR o LR.

➤ Al termine della gestione dell’eccezione, si rimette a posto il contesto e, dopo l’ultimo intervento sul registro MSR con RI, si considera conclusa l’eccezione. In questo modo, per esempio:

lwz r4, 40 (sp)      ; Restore gpr4 from stack
lwz r3, 20 (sp)      ; Restore XER
value from stack mtxer r3               ; Copy XER value
to XER register

Particolare cura deve essere rivolta all’azzeramento del registro MSR[RI].

➤ Si ritorna al flusso del programma interrotto semplicemente utilizzando l’istruzione assembler rfi, questa istruzione copia il contenuto di SRR1 nel registro MSR. Si nota che è compito del gestore dell’eccezione fare una copia dei registri SRR0–SRR1 in modo da poter ripristinare il loro contenuto anche in seguito al verificarsi di un’eccezione annidata con la precedente. E’ sempre compito dell’handler segnalare, attraverso un’apposita manipolazione del bit di RI di MSR, che l’eccezione è adesso recuperabile e di riabilitare o no, in funzione dell’implementazione, le eccezioni.  Il listato 1 ci mostra un possibile esempio di una ISR per la gestione di un timer.

Org 0x00000100
b _start ; System reset exception, per crt0 file
org 0x00000500
b external_interrupt_exception
.text
external_interrupt_exception:
.equ PISCR, 0x2fc240 ; Address of register PISCR
; Start prologue:
; STEP 1: SAVE “MACHINE CONTEXT”
; STEP 2: MAKE MSR[RI] RECOVERABLE
; Omit steps 1, 2- new exceptions during routine are irrecoverable
; STEP 3: SAVE OTHER APPROPRIATE CONTEXT
stwu sp, -24 (sp) ; Create stack frame & store backchain
stw r3, 8 (sp) ; Save only gprs used for this exception
stw r4, 12 (sp)
stw r5, 16 (sp)
mfcr r3 ; Save CR
stw r3, 4 (sp) ; All important registers are now saved
; STEP 4: DETERMINE INTERRUPT SOURCE
lis r4, PISCR@ha ; Load high word of Pointer to PISCR
lhz r3, PISCR@l(r4) ; Load PISCR register value
andi. r5, r3,0x80 ; Check for Interrupt status of the PIT
beq other_interrupt ; If status was not set, check other IRQs
; STEP 5: BRANCH TO INTERRUPT HANDLER
; Perform PIT service routine right here:
sth r3, PISCR@l(r4) ; Negate interrupt request (write a 1)
lis r4, counter@ha ; Load high word of Pointer to counter
lwz r3, counter@l(r4) ; Load counter value to r3
addi r3, r3, 1 ; Increment counter
stw r3, counter@l(r4) ; Write back counter value
; STEP 6: RESTORE CONTEXTS
Epilog: ; Start epilog:
lwz r3, 4 (sp) ; Restore CR
mtcrf 0xff, r3 ; Mask = 1111 1111, restoring CR fields
lwz r3, 8 (sp) ; Restore gprs
lwz r4, 12 (sp)
lwz r5, 16 (sp)
addi sp, sp, 24 ; Restore SP, which frees up stack
; STEP 7: RETURN TO PROGRAM
rfi ; End of Interrupt — return to program
Listato 1 - Esempio di un PIT

 

 

Scrivi un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *