Obsah / Ovladače / DMA / Globální funkce ovladače řadiče DMA
Zdrojový kód:
DRIVERS\SYSTEM\DMA.ASM
Globální
funkce ovladače řadiče DMA
Globální funkce
ovladače řadiče DMA se provádějí s implicitním ovladačem
DMA řadiče, jehož popisovač je uchován v proměnné
DMADevice.
; -----------------------------------------------------------------------------
; DMA global function: Get DMA channel info
; -----------------------------------------------------------------------------
; INPUT: EAX = channel number
; OUTPUT: ECX = number of channels
; EDX = flags (see Channel info flags), 0=invalid channel
; CY = invalid channel number (ECX is valid, EDX = 0)
; NOTES: It locks fast spin-lock of device interface.
; -----------------------------------------------------------------------------
DMAInfo: push ebx ; push EBX
mov ebx,[DMADevice] ; EBX <- current DMA device
DEVFNCLOCKC DEVDMA_Info ; get DMA channel info
pop ebx ; pop EBX
ret
|
Funkce DMAInfo
poskytne informace o kanálu DMA, jehož číslo je funkci
předáno v registru EAX. Na výstupu z funkce je navrácen v
registru ECX počet kanálů DMA a v registru EDX příznaky
(nebo jejich kombinace) s těmito hodnotami: DMAINFO_VALID kanál
je platný, DMAINFO_USED kanál je používán (vlastněn),
DMAINFO_RUNNING na kanálu probíhá přenos dat, DMAINFO_8BIT
kanál je 8-bitový (jinak 16-bitový), DMAINFO_BOUND blok dat
nesmí překročit hranici 64 KB (jinak 128 KB), DMAINFO_ALIGN
adresa musí být zarovnána na slovo, DMAINFO_16M limitace na
nižších 16 MB paměti. V případě neplatného čísla DMA
kanálu navrátí funkce příznak CY a obsah registru EDX je
nulový. Počet kanálů navrácený v registru ECX je i v
případě chyby platný. Funkce zajistí uzamknutí ovladače
pomocí rychlého zámku.
; -----------------------------------------------------------------------------
; DMA global function: Allocate DMA channel
; -----------------------------------------------------------------------------
; INPUT: EAX = channel number
; OUTPUT: CY = cannot allocate, channel allready used
; NOTES: It locks fast spin-lock of device interface.
; -----------------------------------------------------------------------------
DMAAlloc: push ebx ; push EBX
mov ebx,[DMADevice] ; EBX <- current DMA device
DEVFNCLOCKC DEVDMA_Alloc ; allocate DMA channel
pop ebx ; pop EBX
ret
|
Funkce DMAAlloc
slouží k alokaci (přivlastnění) DMA kanálu. Na vstupu
funkce obsahuje registr EAX číslo kanálu DMA, který má být
alokován. V případě chyby (kanál je již alokován nebo
zadáno neplatné číslo kanálu) navrátí funkce příznak
chyby CY. Funkce zajistí uzamknutí ovladače pomocí rychlého
zámku.
; -----------------------------------------------------------------------------
; DMA global function: Free DMA channel
; -----------------------------------------------------------------------------
; INPUT: EAX = channel number
; OUTPUT: CY = invalid channel number or it is already free or it is
; still running
; NOTES: It locks fast spin-lock of device interface.
; -----------------------------------------------------------------------------
DMAFree: push ebx ; push EBX
mov ebx,[DMADevice] ; EBX <- current DMA device
DEVFNCLOCKC DEVDMA_Free ; free DMA channel
pop ebx ; pop EBX
ret
|
Funkce DMAFree
slouží k dealokaci (uvolnění) DMA kanálu. Na vstupu funkce
obsahuje registr EAX číslo kanálu DMA, který má být
uvolněn. V případě chyby (kanál není alokován nebo zadáno
neplatné číslo kanálu nebo probíhá přenos dat) navrátí
funkce příznak chyby CY. Není kontrolováno, zda kanál
uvolňuje stejný vlastník, který si zažádal o jeho alokaci.
Funkce zajistí uzamknutí ovladače pomocí rychlého zámku.
; -----------------------------------------------------------------------------
; DMA global function: Start DMA transfer
; -----------------------------------------------------------------------------
; INPUT: EAX = channel number
; ECX = number of bytes (cannot be 0, max. 64K, word aligned)
; EDX = system address (word aligned)
; ESI = DMA direction (DMADIR_READ, DMADIR_WRITE, DMADIR_VERIFY)
; OUTPUT: CY = invalid argument or channel is already running
; NOTES: Function translates system address to physical address.
; Block cannot cross 64K boundary, size and address must be word
; aligned, size can be max. 64 KB and transfered block
; must be in lower 16MB of physical RAM.
; It locks fast spin-lock of device interface.
; -----------------------------------------------------------------------------
DMAStart: push ebx ; push EBX
mov ebx,[DMADevice] ; EBX <- current DMA device
DEVFNCLOCKC DEVDMA_Start ; start DMA transfer
pop ebx ; pop EBX
ret
|
Funkce DMAStart
odstartuje DMA přenos dat. Na vstupu funkce obsahuje registr EAX
číslo kanálu DMA, na kterém má být přenos odstartován. V
registru ECX je nastaven počet bajtů k přenosu, v registru EDX
adresa paměti v systému (tedy ne fyzické paměti) a v registru
ESI je příznak směru přenosu: DMADIR_READ čtení ze
zařízení, DMADIR_WRITE zápis na zařízení a DMADIR_VERIFY
je verifikace dat ze zařízení. Současná verze ovladače má
následující omezení: blok dat nesmí překrýt hranici adres
64 KB, maximální velikost bloku 64 KB, minimální velikost
bloku 2 B, velikost musí být zarovnaná na slovo, adresa musí
být zarovnaná na slovo a lze používat pouze nižších 16 MB
fyzické paměti (blok získaný pomocí funkce DMAMemAlloc). V
případě neplatného zadání některého z argumentů
navrátí funkce příznak chyby CY. Funkce zajistí uzamknutí
ovladače pomocí rychlého zámku.
; -----------------------------------------------------------------------------
; DMA global function: Stop DMA transfer
; -----------------------------------------------------------------------------
; INPUT: EAX = channel number
; OUTPUT: CY = invalid channel number or channel is not running
; NOTES: It locks fast spin-lock of device interface.
; -----------------------------------------------------------------------------
DMAStop: push ebx ; push EBX
mov ebx,[DMADevice] ; EBX <- current DMA device
DEVFNCLOCKC DEVDMA_Stop ; stop DMA transfer
pop ebx ; pop EBX
ret
|
Funkce DMAStop
zastaví DMA přenos dat. Na vstupu funkce obsahuje registr EAX
číslo kanálu DMA, na kterém má být přenos zastaven. V
případě neplatného čísla kanálu nebo pokud přenos
nebrobíhá navrátí funkce příznak chyby CY. Funkce zajistí
uzamknutí ovladače pomocí rychlého zámku.
; -----------------------------------------------------------------------------
; DMA global function: Get remaining transfer size
; -----------------------------------------------------------------------------
; INPUT: EAX = channel number
; OUTPUT: CY = invalid channel number or channel is not running
; ECX = remaining bytes (0 on error)
; NOTES: It locks fast spin-lock of device interface.
; -----------------------------------------------------------------------------
DMARemain: push ebx ; push EBX
mov ebx,[DMADevice] ; EBX <- current DMA device
DEVFNCLOCKC DEVDMA_Remain ; get remaining transfer size
pop ebx ; pop EBX
ret
|
Funkce DMARemain
zjistí zbývající počet bajtů k přenosu. Na vstupu funkce
obsahuje registr EAX číslo kanálu DMA, ze kterého je potřeba
zjistit počet zbylých dat. Na výstupu funkce je v registru ECX
navrácen počet zbývajících bajtů k přenosu. Hodnota 0
indikuje ukončení přenosu. Při prvním volání (pokud kanál
nebyl dosud inicializován) může být navrácena hodnota 1. V
případě neplatného čísla kanálu nebo pokud přenos
neprobíhá navrátí funkce příznak chyby CY a registr ECX je
vynulován. Funkce zajistí uzamknutí ovladače pomocí
rychlého zámku.
; -----------------------------------------------------------------------------
; DMA global function: Check if channel is still running
; -----------------------------------------------------------------------------
; INPUT: EAX = channel number
; OUTPUT: CY = invalid channel number or channel is not running
; NOTES: It locks fast spin-lock of device interface.
; -----------------------------------------------------------------------------
DMACheck: push ebx ; push EBX
mov ebx,[DMADevice] ; EBX <- current DMA device
DEVFNCLOCKC DEVDMA_Check ; check if channel is still running
pop ebx ; pop EBX
ret
|
Funkce DMACheck
zjistí, zda probíhá přenos dat na kanálu. Na vstupu funkce
obsahuje registr EAX číslo kanálu DMA, na kterém má být
přenos dat zjištěn. Na výstupu funkce je navrácen příznak
CY v případě neplatného čísla kanálu nebo není-li kanál
přidělen nebo pokud přenos dat neprobíhá. Při prvním
volání (pokud kanál nebyl dosud inicializován) může být
navrácen příznak přenosu dat (NC). Funkce se používá jako
rychlejší varianta ke zjištění přenosu dat než DMARemain.
Funkce zajistí uzamknutí ovladače pomocí rychlého zámku.
; -----------------------------------------------------------------------------
; DMA global function: Wait until transfer stops
; -----------------------------------------------------------------------------
; INPUT: EAX = channel number
; EBX = minimal time in ms (0=immediately)
; ECX = maximal time in ms (time-out, 0=immediately)
; EDX = delta time in ms of tests until stops (1 minimal)
; OUTPUT: CY = invalid channel number or it is not running or time-out
; NOTES: It locks fast spin-lock of device interface.
; -----------------------------------------------------------------------------
; ------------- Push registers
DMAWait: push ebx ; push EBX
push ecx ; push ECX (it must be last)
; ------------- Check if channel is valid, used and running
push edx ; push EDX
call DMAInfo ; get DMA channel info
jc DMAWait2 ; invalid channel
and dl,DMAINFO_RUNNING+DMAINFO_USED ; flags
cmp dl,DMAINFO_RUNNING+DMAINFO_USED ; is used + running?
DMAWait2: pop edx ; pop EDX
jc DMAWait8 ; invalid channel or not running
pop ecx ; pop ECX
push ecx ; push ECX
; ------------- Wait for a while
DMAWait3: push eax ; push EAX
mov eax,ebx ; EAX <- time in ms
cmp eax,ecx ; check time-out
jb DMAWait4 ; time-out is OK
mov eax,ecx ; EAX <- limit time-out
DMAWait4: or eax,eax ; any time?
jz DMAWait6 ; no time
call Sleep ; sleep for a while
DMAWait6: sub ecx,ebx ; check time-out
pop eax ; pop EAX
jb DMAWait8 ; time-out
mov ebx,edx ; EBX <- delta time
; ------------- Check if channel is running
call DMACheck ; check if channel is running
jc DMAWait7 ; transfer stops
; ------------- Time-out is 0
or ecx,ecx ; is time-out 0 ?
jnz DMAWait3 ; continue waiting
DMAWait7: cmc ; CY = error flag
; ------------- Pop registers
DMAWait8: pop ecx ; pop ECX
pop ebx ; pop EBX
ret
|
Funkce DMAWait
zajistí čekání na ukončeí DMA přenosu v případě, že
zařízení nepodporuje indikaci ukončení přenosu pomocí
přerušení. Na vstupu funkce obsahuje registr EAX číslo
kanálu DMA. Registr EBX obsahuje minimální čas v [ms], po
který bude čekáno na ukončení přenosu. Do uplynutí
minimálního času nebude prováděn test ukončení DMA
přenosu. Minimální čas může být 0, v tom případě se
první test ukončení přenosu provede okamžitě. Registr ECX
obsahuje maximální čas doby čekání na ukončení přenosu v
[ms]. Pokud do požadované maximální doby nebude přenos
ukončen, funkce se ukončí s navrácením příznaku chyby CY.
Je-li obsah registr ECX nulový a současně obsah registru EBX
je nula, funkce pouze otestuje ukončení přenosu a ihned se
ukončí. Registr EDX obsahuje interval mezi jednotlivými testy
ukončení přenosu v [ms]. Interval musí být minimálně 1 ms.
V případě neplatného čísla kanálu nebo pokud přenos
nebrobíhá nebo pokud přenos nebyl ukončen do uplynutí
maximálního času navrátí funkce příznak chyby CY. Funkce
uzamyká ovladač pomocí rychlého zámku.
Obsah / Ovladače / DMA / Globální funkce ovladače řadiče DMA