Tvůrce webu je i pro tebe! Postav třeba web. Bez grafika. Bez kodéra. Hned.
wz

Obsah / Ovladače / INT / Struktury a makra správce přerušení

Zdrojový kód: INCLUDE\DRIVERS\INT.INC


Struktury a makra správce přerušení


INT_NUM		EQU	32		; total number of interrupt lines
INT_FIRST	EQU	20h		; first interrupt for IRQ
					; (must be multiple of 8)

; ------------- Interrupt descriptor

struc		INTDESC

		resb	LIST_size	; 0: list of IRQ handlers
INTDESC_IRQ:	resb	1		; 8: IRQ number
INTDESC_Flags:	resb	1		; 9: flags (see below)
INTDESC_HandNum:resb	1		; 0Ah: total number of handlers
INTDESC_Active:	resb	1		; 0Bh: number of active handlers
		resd	1		; 0Ch: ...padding

endstruc				; size 10h = 16 bytes

; ------------- Interrupt descriptor flags

INTDESC_VALID	EQU	B0		; interrupt is valid (usable)

Konstanta INT_NUM určuje počet přerušení, které správce přerušení může obsluhovat. Pro INT_NUM = 32 se jedná o přerušení IRQ0 až IRQ31. Konstanta INT_FIRST je číslo vektoru přerušení pro první IRQ. INT_FIRST musí být násobkem 8. Pro INT_FIRST = 20h se jedná o vektory přerušení INT32, INT33, ... INT63.

Struktura INTDESC je popisovač přerušení. Na začátku struktury je záhlaví LIST seznamu ovladačů přerušení.

INTDESC_IRQ je číslo přerušení IRQ patřící tomuto popisovači přerušení.

INTDESC_Flags jsou příznaky - používá se pouze jeden příznak, INTDESC_VALID, označující, že přerušení je platné a může být použito.

INTDESC_HandNum je počet nainstalovaných ovladačů přerušení, tj. počet ovladačů připojených do seznamu. Více ovladačů může sdílet stejné přerušení pouze v případě, že všechny povolují sdílení přerušení.

INTDESC_Active je počet aktivních ovladačů přerušení, tj. ovladače které jsou volány při příchodu přerušení. Je-li aktivován alespoň jeden z ovladačů, je povolena příslušná linka řadiče přerušení. Není-li aktivní ani jeden z ovladačů, je linka řadiče přerušení zakázána.


; ------------- Interrupt handler

struc		INTHAND

		resb	LIST_size	; 0: link to list of IRQ handlers
INTHAND_IntDesc:resd	1		; 8: pointer to interrupt descriptor
INTHAND_Flags:	resb	1		; 0Ch: flags (see below, DWORD aligned)
		resb	1		; 0Dh: ...padding
INTHAND_IRQ:	resb	1		; 0Eh: current IRQ number
INTHAND_Best:	resb	1		; 0Fh: recommended IRQ number (-1=none)
INTHAND_IRQMask:resd	1		; 10h: mask of usable IRQs (1=enabled)
INTHAND_Data:	resd	1		; 14h: user data
INTHAND_Int:	resd	1		; 18h: interrupt handler function
					;	INPUT:	EAX = IRQ number
					;		EBX = user data
					;	Handler must save all registers!
					;      Private handler has no input.
		resd	1		; 1Ch: ...padding

endstruc				; size 20h = 32 bytes

; ------------- Interupt handler flags

INT_SHARE	EQU	B0		; IRQ can be shared
INT_PRIVATE	EQU	B1		; private handling (with own handler)
INT_ACTIVE_BIT	EQU	2		; (bit number of IRQ_ACTIVE flag)
INT_ACTIVE	EQU	(1 << INT_ACTIVE_BIT) ; handler is active (enabled)

Struktura INTHAND je popisovač ovladače přerušení. Na začátku je položka LIST seznamu všech ovladačů pro jedno přerušení.

INTHAND_IntDesc je ukazatel na popisovač přerušení INTDESC, ke kterému je tento ovladač přerušení připojený.

INTHAND_Flags jsou příznaky. INT_SHARE je příznak, že přerušení může být sdíleno s jinými ovladači. Pokud přijde přerušení, jsou vyvolány obslužné funkce všech ovladačů, které k danému přerušení patří. Zda přerušení patří k danému ovladači si musí ovladač ověřit sám. Povolením možnosti sdílení přerušení se zvýší šance nalezení volného přerušení při instalaci ovladače přerušení. INT_PRIVATE je příznak privátního ovladače přerušení. Je-li tento příznak nastaven, nastaví se vektor přerušení přímo na funkci ovladače přerušení a přerušení neprochází přes správce přerušení. V tom případě musí ovladač přerušení zajistit sám potvrzení přerušení (pomocí IRQAck), funkce musí končit instrukcí IRET (návrat z přerušení) a uvnitř funkce se může uzamykat zámek správce přerušení. Privátní ovladač nesmí mít zapnut příznak sdílení přerušení. Příznak INT_ACTIVE indikuje, že ovladač je aktivní, tj. bude obsluhován při příchodu přerušení. Je-li příznak nastaven před instalací ovladače, bude přerušení aktivováno automaticky už během instalace ovladače. INT_ACTIVE_BIT je číslo bitu příznaku INT_ACTIVE.

INTHAND_IRQ udává aktuální číslo přerušení přidělené ovladači přerušení správcem přerušení.

INTHAND_Best je doporučené číslo přerušení. Během instalace ovladače přerušení se správce přerušení pokouší nainstalovat ovladač nejdříve pro doporučené přerušení a to i za cenu sdílení přerušení s jinými ovladači (tedy pokud je sdílení povoleno). Nelze-li přerušení nainstalovat k doporučenému přerušení, pak teprve proběhne instalace podle masky povolených přerušení. Hodnota -1 (tj. 0FFh) znamená, že žádné přerušení není doporučeno.

INTHAND_IRQMask je 32-bitová maska povolených přerušení. Je-li příslušný bit nastaven na hodnotu 1, je povolena instalace pro dané přerušení. Správce přerušení se při instalaci přerušení pokouší najít takové přerušení, které je maskou přerušení povoleno a které má současně nainstalovaný nejmenší počet ovladačů přerušení.

INTHAND_Data jsou uživatelská data, která jsou předána funkci ovladače přerušení při příchodu přerušení. Položka může obsahovat libovolná data, která si ovladač sem uloží a může být kdykoliv dodatečně ovladačem měněna.

INTHAND_Int je ukazatel na funkci ovladače přerušení. Tato funkce je volána vždy při příchodu přerušení, je-li příslušný ovladač aktivní. Na vstupu funkce je v registru EAX předáno číslo přerušení IRQ a v registru EBX jsou předána uživatelská data, která byla uchována v položce INTHAND_Data. Funkce musí uchovat obsahy všech registrů a nesmí uzamykat zámek správce přerušení - může použít pouze funkce IntIntAct a IntIntDeact. Funkce musí proběhnout celá se zákazem přerušení (při vstupu do funkce je přerušení již zakázáno) a musí být rychlá, během její obsluhy je činnost systému zastavena.

V případě privátního ovladače (nastavený příznak INT_PRIVATE) nahradí ukazatel na funkci standardní vektor přerušení, který jinak používá správce přerušení, proto v tomto případě musí funkce obsahovat potvrzení přerušení (pomocí IRQAck), na vstupu funkce jsou všechny registry nedefinované (funkci se nic nepředává), funkce musí končit instrukcí IRET, uvnitř funkce se může uzamykat zámek správce přerušení a funkce může během své obsluhy povolit přerušení.


; ------------- Initialized interrupt handler
; Parameters: %1 = flags, %2 = recommended IRQ number (-1=none),
; %3 = mask of usable IRQs (1=enabled), %4 = interrupt handler

%macro		INTHANDLER 4

%%L1:
		LISTHEAD		; link to list of IRQ handlers
		dd	NULL		; pointer to interrupt descriptor
		db	%1		; interrupt handler flags
		db	0		; ...padding
		db	-1		; current IRQ number
		db	%2		; recommended IRQ number (-1=none)
		dd	%3		; mask of usable IRQs (1=enabled)
		dd	%%L1		; user data
		dd	%4		; interrupt handler
		dd	0		; ...padding
%endmacro

Makro INTHANDLER je inicializovaný popisovač ovladače přerušení. Makro má 4 parametry:

%1 - příznaky (viz položka INTHAND_Flags)

%2 - číslo doporučeného přerušení IRQ (-1 = není žádné doporučené IRQ)

%3 - maska povolených přerušení IRQ (má-li bit hodnotu 1 = přerušení je povoleno)

%4 - ukazatel na funkci ovladače přerušení

Položka uživatelských dat INTHAND_Data obsahuje implicitně ukazatel na tento popisovač ovladače přerušení.


Obsah / Ovladače / INT / Struktury a makra správce přerušení