dma (bus mastering pci) - Dipartimento di Ingegneria dell`Informazione

Transcript

dma (bus mastering pci) - Dipartimento di Ingegneria dell`Informazione
DMA
(BUS MASTERING PCI)
G. Frosini DMA
Slide 1
Accesso Diretto alla Memoria
•
Tecniche di ingresso/uscita a controllo di programma e a
interruzione di programma:
– il trasferimento di un dato tra una locazione di memoria e il registro dati
di un'interfaccia richiede l'esecuzione di più istruzioni da parte del
processore.
•
Casi particolari:
– velocità di trasferimento superiore a quella di esecuzione delle istruzioni
(trasferimento dati da/verso un disco magnetico od ottico);
– non opportuno occupare il processore con le istruzioni per il trasferimento
tra memoria e interfaccia, in modo da utilizzarlo per altre elaborazioni.
•
Utilizzo della tecnica di accesso diretto alla memoria (DMA: Direct
Memory Access):
– i trasferimenti dati fra la memoria e un’interfaccia avvengono senza
l'intervento continuo del processore.
G. Frosini DMA
Slide 2
Bus Mastering
•
Bus PCI:
– prevede una forma di DMA nota come Bus Mastering.
•
Dispositivo collegato al bus PCI:
– può essere iniziatore di una transazione avente come obiettivo il ponte Ospite-PCI;
– tramite tale ponte, l’iniziatore può accedere alla memoria centrale.
•
Transazione sul bus PCI che specifica un indirizzo della memoria centrale
(memoria collegata fisicamente al bus locale):
– il ponte Ospite-PCI:
•
•
•
•
•
risponde divenendo l’obiettivo alla transazione;
si impossessa del bus locale sostituendosi al processore;
comanda il trasferimento da o verso la memoria;
completa la transazione PCI.
Controllo del bus locale:
– viene gestito da un apposito arbitro, che concede l'utilizzo del bus a un richiedente
alla volta (gestione in mutua esclusione).
•
Entità che utilizzano il bus locale:
– ipotesi: solo il processore e il ponte Ospite-PCI;
– in questo caso l'arbitraggio del bus locale viene effettuato dal processore.
G. Frosini DMA
Slide 3
Colloquio fra processore e ponte Ospite-PCI (1)
•
Processore:
– dotato di una coppia di piedini /HOLD e /HOLDA, mediante i quali riceve
le richieste di utilizzo del bus locale e invia le risposte di accettazione.
•
Ponte Ospite-PCI:
– dotato di due piedini omonimi /HOLD e /HOLDA, collegati a quelli del
processore;
– avviene un colloquio per concordare chi dei due ha il controllo del bus:
• condizione iniziale: /HOLD e /HOLDA sono entrambi disattivi, e il
processore ha il controllo del bus (i piedini di uscita del ponte verso il bus
locale sono in alta impedenza);
• il ponte attiva il piedino /HOLD, chiedendo al processore l'utilizzo del bus
locale;
• il processore, dopo aver completato l'eventuale ciclo di bus in corso, si
disconnette dal bus locale (pone i piedini di uscita verso il bus locale in alta
impedenza) e attiva il piedino /HOLDA;
• il ponte si impossessa del bus locale e, dopo averlo utilizzato, disattiva il
piedino /HOLD (pone nuovamente i piedini di uscita verso il bus locale in
alta impedenza);
• il processore chiude il colloquio con il ponte disattivando il piedino
/HOLDA e assume nuovamente il controllo del bus locale.
G. Frosini DMA
Slide 4
Colloquio fra processore e ponte Ospite-PCI (2)
•
Processore:
– privilegia le richieste esterne di utilizzo del bus rispetto alle proprie
necessità interne;
– ciò per evitare la possibile perdita di dati quando le richieste provengono
da una periferica con elevata velocità di trasferimento.
•
Presenza del controllore della memoria cache:
– il controllore della memoria cache è quello che utilizza effettivamente il
bus locale;
– esso possiede i piedini /HOLD e /HOLDA;
– le richieste di utilizzo del bus locale sono fatte dal ponte al controllore
della memoria cache;
• il piedino di ingresso /HOLD del processore è collegato
permanentemente all’alimentazione (disattivo);
• il piedino di uscita /HOLDA del processore (disattivo) è lasciato
scollegato.
G. Frosini DMA
Slide 5
Arbitraggi del Bus PCI e del Bus Locale
Bus Locale
/HOLD
Processore
Cache
Ponte
Ospite-PCI
Memoria
/HOLDA
Bus PCI
/REQ
/REQ
Arbitro
/GNT
Iniziatore
/GNT
G. Frosini DMA
Slide 6
Operazioni in Bus Mastering (1)
•
Command register di una funzione (spazio di configurazione):
– bit n. 2: se posto ad 1 abilita la funzione a operare in bus mastering;
– bit n. 1 e bit n. 0: se posti a 1 abilitano la funzione, rispettivamente, a rispondere a
transazioni nello spazio di memoria o di I/O.
•
Trasferimento in Bus Mastering:
– può coinvolgere uno o più buffer di memoria;
– richiede che venga preparata in memoria una tabella dei descrittori di buffer.
•
Descrittore di buffer:
– struttura dati con tre informazioni:
• indirizzo (multiplo di 4) del buffer nello spazio di memoria (espresso con 32 bit);
• numero di byte (valore multiplo di 4) della porzione di buffer da utilizzare (espressa
con 16 bit);
• flag EOT (End Of Table) che indica se questo descrittore è l'ultimo (EOT vale 1) o
meno (EOT vale 0) nella tabella dei descrittori di buffer.
31
15
0
Indirizzo del buffer
EOT
Numero di byte
G. Frosini DMA
Slide 7
Operazioni in Bus Mastering (2)
•
Funzioni con capacità di Bus Mastering:
– implementano tre registri, tipicamente nello spazio di I/O (un blocco di 16 byte):
• un registro di comando BMCMD (Bus Mastering CoMmanD register), che specifica
se il trasferimento richiesto è dalla funzione verso la memoria o viceversa;
• un registro di stato BMSTR (Bus Mastering StaTus Register), destinato a contenere
informazioni sullo stato dell'ultimo trasferimento (per esempio, presenza di errori);
• un registro puntatore BMDTPR (Bus Mastering Descriptor Table Pointer Register),
che contiene l’indirizzo della tabella dei descrittori di buffer.
Memoria centrale
Funzione
Spazio di configurazione
Command register
Indirizzo buffer
Blocco
(tipicamente di I/O)
EOT
N. byte
BMCMD
Base register
BMSTR
BMDTPR
Buffer
G. Frosini DMA
Slide 8
Operazioni in Bus Mastering (3)
•
Consideriamo un trasferimento dati dalla funzione verso la memoria:
– ipotesi semplificativa:
•
•
la tabella dei descrittori di buffer contiene un unico descrittore (il flag EOT vale 1).
Quando avviene una scrittura in BMCMD, la funzione (inizio operazione):
– preleva (tramite una transazione PCI con due fasi dati) il descrittore puntato da
BMDTPR, costituito da due parole lunghe:
•
•
indirizzo del buffer;
numero di byte e Flag EOT;
– memorizza le quantità lette in registri interni, siano BUF, NUM ed EOT;
– esegue quindi ciclicamente i seguenti passi:
1. quando si rendono disponibili dei dati da trasferire, siano N (N è memorizzato in un
registro interno ed è multiplo di 4), effettua una transazione PCI di scrittura in
memoria (tramite il ponte Ospite-PCI), all'indirizzo specificato da BUF;
2. in ogni fase dati della transazione trasferisce 4 byte, decrementando N e NUM di 4 e
incrementando BUF di 4 (per predisporre la fase di indirizzamento della eventuale
transazione successiva); quando almeno uno tra N e NUM diventa 0, fa terminare la
transazione PCI e passa al punto seguente;
3. se NUM è diverso da zero torna al punto 1), altrimenti (nel caso di un solo descrittore
EOT vale 1) aggiorna il registro BMSTR e invia una richiesta di interruzione.
G. Frosini DMA
Slide 9
Operazioni in Bus Mastering (4)
•
Routine che va in esecuzione per effetto di questa interruzione:
–
legge il contenuto del registro BMSTR:
•
•
Obiettivo della transazione PCI eseguita al punto 1 (slide precedente):
–
–
•
questa operazione viene riconosciuta come risposta alla richiesta di interruzione
effettuata dalla funzione.
ponte Ospite-PCI;
tale ponte, usando i piedini /HOLD e /HOLDA, assume il controllo del bus locale e
quindi esegue una o più operazioni di scrittura in memoria.
Tabella dei descrittori di buffer (in generale):
–
–
contiene più di un descrittore;
al punto 3) (slide precedente), nel caso in cui NUM valga 0 ma anche EOT valga 0
(ci sono altri descrittori di buffer), la funzione:
•
•
•
incrementa BMDTPR di 8;
preleva dalla memoria un nuovo descrittore di buffer, memorizzando nuovi valori
in BUF, NUM e EOT;
torna al punto 1) (slide precedente).
G. Frosini DMA
Slide 10
Dimensioni e allineamento del Buffer
•
Dimensioni del buffer e numero di byte:
–
–
–
•
in genere non coincidono;
uno stesso buffer può venir utilizzato per operazioni diverse in bus mastering;
la dimensione del buffer (DIM) è la massima delle varie quantità “Numero di byte”
per le varie operazioni.
Operazione in bus mastering (slide 9):
2. in ogni fase dati della transazione trasferisce 4 byte, decrementando N e NUM di 4 e
incrementando BUF di 4; quando almeno uno tra N e NUM diventa 0, fa terminare
la transazione PCI e passa al punto successivo.
–
–
per le precedenti operazioni viene normalmente utilizzato un sommatore a 16 bit
(NUM è rappresentato su 16 bit);
occorre che:
•
l’incremento di BUF non dia luogo a un riporto del sommatore, e quindi che il
buffer si trovi all’interno di una porzione di memoria di 2**16 = 64K;
–
–
se DIM è uguale a 64K, BUFF deve essere allineato a 64K;
se DIM ha un valore sottomultiplo di 64K (per esempio, 4K), è sufficiente che il buffer sia
allineato a quel valore (per esempio, 4K).
G. Frosini DMA
Slide 11
Esempio di Trasferimento (1)
•
Funzione che effettua trasferimenti in Bus Mastering (ipotesi):
– coordinate PCI: costanti BUS (vale 0), DEV, e FUN;
– collegata al piedino IRQ del controllore APIC;
– implementa un blocco, tipicamente di I/O, che contiene i registri specifici
per il Bus Mastering, BMCMD, BMSTR e BMDTPR, ciascuno lungo 32
bit;
– indirizzo del blocco di I/O:
• contenuto nel registro base numero REGB:
– i registri BMCMD, BMSTR, BMDTPR sono allocati uno di seguito all’altro, a
incrementi di 4 byte.
•
Operazioni preliminari:
– leggere il registro base numero REGB, per ottenere l’indirizzo del blocco
di I/O e calcolare gli indirizzi dei registri BMSTR, BMCMD, BMDTPR;
– abilitare transazioni nello spazio di I/O e funzionalità di Bus Mastering
tramite il Command Register (16 bit, spazio di configurazione, offset 4).
G. Frosini DMA
Slide 12
Esempio di Trasferimento (2)
const natb BUS = 0;
const natb DEV = …;
const natb FUN = …;
const natb REGB = …;
ioaddr iBMCMD, iBMSTR, iBMDTPR;
void init_bm()
{
natl base; natw cmd;
base = pci_read_confl(BUS, DEV, FUN, 16+4*REGB);
// registro base numero REGB, che indirizza un blocco di I/O
base &= 0xFFFFFFFE;
// bit n. 0 viene posto a 0 (valeva 1, blocco di I/0); bit n. 1 e 2 valgono già 0 (blocco di 16 byte)
iBMCMD = base;
iBMSTR = base + 4;
iBMDTPR = base + 8;
cmd = pci_read_confw(BUS, DEV, FUN, 4);
// lettura del Command Register (spazio di configurazione, offset 4)
pci_write_confw(BUS, DEV, FUN, 4, cmd | 0x0005);
// abilitazione a rispondere a transazioni nello spazio di I/O (bit n. 0),
// per leggere o scrivere nel blocco di I/O contenente i registri BMCMD, BMSTR ,BMDTPR;
// abilitazione della funzionalità di bus mastering (bit n. 2):
}
G. Frosini DMA
Slide 13
Esempio di Trasferimento (3)
•
Programma:
– costituito dai quattro file rdma.cpp, rdma.s, mod_rdma.s e
mod_rdma.cpp (quest’ultimo contiene anche la precedente funzione
init_bm()).
// fle rdma.cpp
#include <libce.h>
extern natb buf_rdma[];
// definito in Assembler per l’allineamento
extern "C" void go_rdma(natb nn, natb vv[]);
int main()
{ natl quanti = …;
// max 2**16
// ...
go_rdma(quanti, buf_rdma);
// ...
return 0;
}
G. Frosini DMA
Slide 14
Esempio di Trasferimento (4)
# file rdma.s
.data
.align
.global
_buf_rdma:
.text
.global
_go_rdma:
# file mod_rdma.s
.text
.extern
.global
_a_go_rdma:
.extern
.global
_a_driver_rdma:
65536
_buf_rdma
.space
65536
# allineamento a 2**16 = 65536
_go_rdma
int
$200
ret
_c_go_rdma
_a_go_rdma
# dichiarazione necessaria per la funzione ini()
call
_c_go_rdma # routine INT $200
iret
_c_driver_rdma
_a_driver_rdma
# dichiarazione necessaria per la funzione ini()
pushal
# piedino IRQ, tipo 100
call
_c_driver_rdma
movl
$0, 0xFEE000B0
# invio di End Of Interrupt
popal
iret
G. Frosini DMA
Slide 15
Esempio di Trasferimento (5)
// file mode_rdma.cpp
#include <libce.h>
const natb BUS = 0; const natb DEV = …; const natb FUN = …; const natb REGB = …;
ioaddr iBMCMD, iBMSTR, iBMDTPR;
void init_bm()
{
...
}
const natl sincr_rdma = …;
const natl IRQ = …;
natl prd[2];
extern “C” void a_go_rdma();
extern “C” void a_driver_rdma();
void ini()
{
init_bm();
gate_init(200, a_go_rdma);
gate_init(100, a_driver_rdma);
apic_set_VECT(IRQ, 100);
// piedino IRQ con tipo 100
apic_set_MIRQ(IRQ, false);
// abilitazione piedino IRQ dello APIC
}
G. Frosini DMA
Slide 16
Esempio di Trasferimento (6)
extern "C" void c_go_rdma(natl a, natl b, natl c, natl d, natl quanti, natb vv[])
{
const natl LAV = … ;
natb work;
prd[0] = reinterpret_cast<natl>(&vv[0]);
// scrittura in prd
prd[1] = 0x80000000 | quanti;
// EOT posto a 1
outputl(reinterpret_cast<natl>(&prd[0]), iBMDTPR); // scrittura in BMDTPR
outputl(LAV, iBMCMD);
// verso del trasferimento (lettura da PCI-scrittura in memoria), avvio dell’operazione
sem_wait(sincr_rdma);
}
extern "C" void c_driver_rdma()
{
natl work;
inputl(iBMSTR, work);
// risposta alla richiesta di interruzione
// …
sem_signal(sincr_rdma);
}
G. Frosini DMA
Slide 17
DMA con Memoria Cache (1)
•
Memoria Cache funzionante in modo write through:
– trasferimento diretto verso la memoria centrale (con modifica dei dati contenuti
nella memoria centrale stessa):
• le eventuali informazioni che risiedono anche nella memoria cache, devono essere
aggiornate anche nella memoria cache stessa, o invalidate;
– trasferimento diretto dalla memoria centrale:
• non è necessaria alcuna azione.
•
Soluzione diffusa:
– costruire il controllore della memoria cache in modo che sia esso stesso, in caso di
operazione di scrittura, ad aggiornare la memoria cache stessa:
• il controllore, ogni volta che attiva il segnale /HOLDA, esamina anche il valore
dell’indirizzo presente sul bus indirizzi e il tipo di operazione (informazioni emesse
del ponte Ospite-PCI);
• se l’operazione è di scrittura (/MWR diviene attivo), il controllore (in caso di
successo della memoria cache) comanda la scrittura in cache del dato presente sul
bus dati (in tal modo aggiorna anche la memoria cache).
G. Frosini DMA
Slide 18
DMA con Memoria Cache (2)
Controllore
cache
Tranceiver
A31-A0 bus
/BE3-/BE0 bus
D31-D0 bus
/OE
T/R
/MWR bus
/HOLDA
G. Frosini DMA
Slide 19
DMA con Memoria Cache (3)
•
Memoria Cache funzionante in modo write back:
– trasferimento diretto dalla memoria centrale (che potrebbe essere non
aggiornata):
• gli eventuali dati che risiedono anche nella memoria cache, dovrebbero essere
preventivamente invalidati (con aggiornamento della memoria centrale), oppure
essere restituiti al posto di quelli contenuti nella memoria;
•
Soluzione diffusa:
– prevedere collegamenti opportuni fra ponte Ospite-PCI e Controllore della
memoria cache, in modo da effettuare le seguenti azioni:
• in caso di operazione di lettura, verificare se la memoria cache dà successo o
fallimento:;
• nel primo caso, prelevare i dati dalla cache stessa e impedire che vengano prelevati
dalla memoria centrale.
G. Frosini DMA
Slide 20