- Disable interrupts while in HalpLowerIrql

- Properly handle IRR.
- Call IRR Handlers through the SWINT table.

svn path=/trunk/; revision=23659
This commit is contained in:
Alex Ionescu 2006-08-23 01:07:14 +00:00
parent 9f38dc5900
commit 955d04b6ff
2 changed files with 15 additions and 23 deletions

View file

@ -93,7 +93,8 @@ SoftIntByteTable:
.byte DISPATCH_LEVEL /* IRR 6 */ .byte DISPATCH_LEVEL /* IRR 6 */
.byte DISPATCH_LEVEL /* IRR 7 */ .byte DISPATCH_LEVEL /* IRR 7 */
SoftIntHandlerTable: .globl _SoftIntHandlerTable
_SoftIntHandlerTable:
.long _KiUnexpectedInterrupt /* PASSIVE_LEVEL */ .long _KiUnexpectedInterrupt /* PASSIVE_LEVEL */
.long _HalpApcInterrupt /* APC_LEVEL */ .long _HalpApcInterrupt /* APC_LEVEL */
.long _HalpDispatchInterrupt /* DISPATCH_LEVEL */ .long _HalpDispatchInterrupt /* DISPATCH_LEVEL */
@ -179,7 +180,7 @@ _@HalRequestSoftwareInterrupt@4:
/* Call the pending interrupt */ /* Call the pending interrupt */
jmp $ jmp $
call SoftIntHandlerTable[edx*4] call _SoftIntHandlerTable[edx*4]
AfterCall: AfterCall:

View file

@ -23,8 +23,8 @@ UCHAR Table[8] =
2, 2, 2, 2 2, 2, 2, 2
}; };
VOID HalpDispatchInterrupt(VOID); typedef VOID (*PSW_HANDLER)(VOID);
VOID HalpApcInterrupt(VOID); extern PSW_HANDLER SoftIntHandlerTable[];
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
@ -34,6 +34,10 @@ VOID STATIC
HalpLowerIrql(KIRQL NewIrql) HalpLowerIrql(KIRQL NewIrql)
{ {
ULONG Mask; ULONG Mask;
ULONG Flags;
Ki386SaveFlags(Flags);
Ki386DisableInterrupts();
if (KeGetPcr()->Irql > DISPATCH_LEVEL) if (KeGetPcr()->Irql > DISPATCH_LEVEL)
{ {
@ -46,34 +50,21 @@ HalpLowerIrql(KIRQL NewIrql)
if (NewIrql >= PROFILE_LEVEL) if (NewIrql >= PROFILE_LEVEL)
{ {
KeGetPcr()->Irql = NewIrql; KeGetPcr()->Irql = NewIrql;
Ki386RestoreFlags(Flags);
return; return;
} }
if (NewIrql >= DISPATCH_LEVEL) if (NewIrql >= DISPATCH_LEVEL)
{ {
KeGetPcr()->Irql = NewIrql; KeGetPcr()->Irql = NewIrql;
Ki386RestoreFlags(Flags);
return; return;
} }
KeGetPcr()->Irql = DISPATCH_LEVEL; KeGetPcr()->Irql = NewIrql;
if (Table[KeGetPcr()->IRR] >= NewIrql) if (Table[KeGetPcr()->IRR] > NewIrql)
{ {
if (Table[KeGetPcr()->IRR] == DISPATCH_LEVEL) SoftIntHandlerTable[Table[KeGetPcr()->IRR]]();
{
HalpDispatchInterrupt();
}
} }
KeGetPcr()->Irql = APC_LEVEL; Ki386RestoreFlags(Flags);
if (NewIrql == APC_LEVEL)
{
return;
}
if (Table[KeGetPcr()->IRR] >= NewIrql)
{
if (Table[KeGetPcr()->IRR] == APC_LEVEL)
{
HalpApcInterrupt();
}
}
KeGetPcr()->Irql = PASSIVE_LEVEL;
} }
/********************************************************************** /**********************************************************************