From 4e5173d7d0afd90e305501298af13904aa4b9e7a Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Tue, 22 Aug 2006 20:50:52 +0000 Subject: [PATCH] - Commit current work on IRQ rewrite. Currently in a very ugly/dirty state of flux between the new ASM code (with tiny hacks) and the old C code (with giant hacks). I feel that this is a good/stable middle ground before continuing further with the changes. svn path=/trunk/; revision=23649 --- reactos/hal/halx86/generic/generic.rbuild | 1 + reactos/hal/halx86/generic/irq.S | 649 ++++++++++++++++++++++ reactos/hal/halx86/generic/irql.c | 307 ++-------- reactos/hal/halx86/generic/spinlock.c | 25 + reactos/hal/halx86/include/halp.h | 2 +- reactos/include/ndk/asm.h | 3 +- reactos/ntoskrnl/ex/init.c | 4 + 7 files changed, 715 insertions(+), 276 deletions(-) create mode 100644 reactos/hal/halx86/generic/irq.S diff --git a/reactos/hal/halx86/generic/generic.rbuild b/reactos/hal/halx86/generic/generic.rbuild index ff8eb89d865..8acc2e556cd 100644 --- a/reactos/hal/halx86/generic/generic.rbuild +++ b/reactos/hal/halx86/generic/generic.rbuild @@ -32,6 +32,7 @@ ipi.c irql.c + irq.S processor.c resource.c spinlock.c diff --git a/reactos/hal/halx86/generic/irq.S b/reactos/hal/halx86/generic/irq.S new file mode 100644 index 00000000000..f26e6d0fa73 --- /dev/null +++ b/reactos/hal/halx86/generic/irq.S @@ -0,0 +1,649 @@ +/* + * FILE: hal/halx86/generic/irql.S + * COPYRIGHT: See COPYING in the top level directory + * PURPOSE: Software, System and Hardware IRQ Management + * PROGRAMMER: Alex Ionescu (alex@relsoft.net) + */ + +/* INCLUDES ******************************************************************/ + +#include +#include +.intel_syntax noprefix + +.extern _Kei386EoiHelper@0 +.extern _KiUnexpectedInterrupt + +/* GLOBALS *******************************************************************/ + +PICInitTable: + + /* Master PIC */ + .short 0x20 /* Port */ + .byte 0x11 /* Edge,, cascade, CAI 8, ICW4 */ + .byte 0x40 /* Base */ + .byte 4 /* IRQ 4 connected to slave */ + .byte 1 /* Non buffered, not nested, 8086 */ + + /* Slave PIC */ + .short 0xA0 /* Port */ + .byte 0x11 /* Edge, cascade, CAI 8, ICW4 */ + .byte 0x48 /* Base */ + .byte 2 /* Slave ID: Slave 2 */ + .byte 1 /* Non buffered, not nested, 8086 */ + + /* End of initialization table */ + .short 0 + +.globl _KiI8259MaskTable +_KiI8259MaskTable: + .long 0 /* IRQL 0 */ + .long 0 /* IRQL 1 */ + .long 0 /* IRQL 2 */ + .long 0 /* IRQL 3 */ + .long 0xFF800000 /* IRQL 4 */ + .long 0xFFC00000 /* IRQL 5 */ + .long 0xFFE00000 /* IRQL 6 */ + .long 0xFFF00000 /* IRQL 7 */ + .long 0xFFF80000 /* IRQL 8 */ + .long 0xFFFC0000 /* IRQL 9 */ + .long 0xFFFE0000 /* IRQL 10 */ + .long 0xFFFF0000 /* IRQL 11 */ + .long 0xFFFF8000 /* IRQL 12 */ + .long 0xFFFFC000 /* IRQL 13 */ + .long 0xFFFFE000 /* IRQL 14 */ + .long 0xFFFFF000 /* IRQL 15 */ + .long 0xFFFFF800 /* IRQL 16 */ + .long 0xFFFFFC00 /* IRQL 17 */ + .long 0xFFFFFE00 /* IRQL 18 */ + .long 0xFFFFFE00 /* IRQL 19 */ + .long 0xFFFFFE80 /* IRQL 20 */ + .long 0xFFFFFEC0 /* IRQL 21 */ + .long 0xFFFFFEE0 /* IRQL 22 */ + .long 0xFFFFFEF0 /* IRQL 23 */ + .long 0xFFFFFEF8 /* IRQL 24 */ + .long 0xFFFFFEF8 /* IRQL 25 */ + .long 0xFFFFFEFA /* IRQL 26 */ + .long 0xFFFFFFFA /* IRQL 27 */ + .long 0xFFFFFFFB /* IRQL 28 */ + .long 0xFFFFFFFB /* IRQL 29 */ + .long 0xFFFFFFFB /* IRQL 30 */ + .long 0xFFFFFFFB /* IRQL 31 */ + +#if 0 +HalpSysIntHandler: +.rept 8 + .long GenericIRQ /* IRQ 0-7 */ +.endr + .long IRQ7 /* IRQ 7 */ +.rept 8 + .long GenericIRQ /* IRQ 8-15 */ +.endr + .long IRQ15 /* IRQ 15 */ +.rept 20 + .long GenericIRQ /* IRQ 16-35 */ +.endr +#endif + +SoftIntByteTable: + .byte PASSIVE_LEVEL /* IRR 0 */ + .byte PASSIVE_LEVEL /* IRR 1 */ + .byte APC_LEVEL /* IRR 2 */ + .byte APC_LEVEL /* IRR 3 */ + .byte DISPATCH_LEVEL /* IRR 4 */ + .byte DISPATCH_LEVEL /* IRR 5 */ + .byte DISPATCH_LEVEL /* IRR 6 */ + .byte DISPATCH_LEVEL /* IRR 7 */ + +SoftIntHandlerTable: + .long _KiUnexpectedInterrupt /* PASSIVE_LEVEL */ + .long _HalpApcInterrupt /* APC_LEVEL */ + .long _HalpDispatchInterrupt /* DISPATCH_LEVEL */ + +SoftIntHandlerTable2: + .long _KiUnexpectedInterrupt /* PASSIVE_LEVEL */ + .long _HalpApcInterrupt2ndEntry /* APC_LEVEL */ + .long _HalpDispatchInterrupt2ndEntry /* DISPATCH_LEVEL */ + +/* FUNCTIONS *****************************************************************/ + +.globl _HalpInitPICs@0 +.func HalpInitPICs@0 +_HalpInitPICs@0: + + /* Save ESI and disable interrupts */ + push esi + pushf + cli + + /* Read the init table */ + lea esi, PICInitTable + lodsw + +InitLoop: + + /* Put the port in EDX */ + movzx edx, ax + + /* Initialize the PIC, using a delay for each command */ + outsb + jmp $+2 + inc edx + outsb + jmp $+2 + outsb + jmp $+2 + outsb + jmp $+2 + + /* Mask all interrupts */ + mov al, 0xFA // FIXME: Should be 0xFF + out dx, al + + /* Check if we're done, otherwise initialize next PIC */ + lodsw + cmp ax, 0 + jnz InitLoop + + /* Restore interrupts and return */ + or dword ptr [esp], EFLAGS_INTERRUPT_MASK + popf + pop esi + ret +.endfunc + +.globl @HalRequestSoftwareInterrupt@4 +.func @HalRequestSoftwareInterrupt@4 +_@HalRequestSoftwareInterrupt@4: +@HalRequestSoftwareInterrupt@4: + + /* Get IRR mask */ + mov eax, 1 + shl eax, cl + + /* Disable interrupts */ + pushf + cli + + /* Set IRR and get IRQL */ + or [fs:KPCR_IRR], eax + mov cl, [fs:KPCR_IRQL] + + /* Get software IRR mask */ + mov eax, [fs:KPCR_IRR] + and eax, 3 + + /* Get highest pending software interrupt and check if it's higher */ + xor edx, edx + mov dl, SoftIntByteTable[eax] + cmp dl, cl + jbe AfterCall + + /* Call the pending interrupt */ + jmp $ + call SoftIntHandlerTable[edx*4] + +AfterCall: + + /* Retore interrupts and return */ + popf + ret +.endfunc + +.globl _HalDisableSystemInterrupt@8 +.func HalDisableSystemInterrupt@8 +_HalDisableSystemInterrupt@8: + + /* Convert to vector */ + movzx ecx, byte ptr [esp+4] + sub ecx, PRIMARY_VECTOR_BASE + + /* Disable interrupts and set the new IDR */ + mov edx, 1 + shl edx, cl + cli + or [fs+KPCR_IDR], edx + + /* Get the current mask */ + xor eax, eax + in al, 0xA1 + shl eax, 8 + in al, 0x21 + + /* Mask off the interrupt and write the new mask */ + or eax, edx + out 0x21, al + shr eax, 8 + out 0xA1, al + + /* Return with interrupts enabled */ + in al, 0xA1 + sti + ret 8 +.endfunc + +#if 0 +.globl _HalEnableSystemInterrupt@12 +.func HalEnableSystemInterrupt@12 +_HalEnableSystemInterrupt@12: + + /* Get the vector and validate it */ + jmp $ + movzx ecx, byte ptr [esp+4] + sub ecx, PRIMARY_VECTOR_BASE + jb Invalid + cmp ecx, CLOCK2_LEVEL + jnb Invalid + + /* Get the current PCI Edge/Level control registers */ + mov edx, 0x4D1 + in al, dx + shl ax, 8 + mov eax, 0x4D0 + in al, dx + mov dx, 1 + shl dx, cl + + /* Check if this is a latched interrupt */ + cmp dword ptr [esp+12], 0 + jnz Latched + + /* Use OR for edge interrupt */ + or ax, dx + jmp AfterMask +Latched: + + /* Mask it out for level interrupt */ + not dx + and ax, dx + +AfterMask: + + /* Set the PCI Edge/Level control registers */ + mov edx, 0x4D0 + out dx, al + shr ax, 8 + mov edx, 0x4D1 + out dx, al + + /* Calculate the new IDR */ + mov eax, 1 + shl eax, cl + not eax + cli + and [fs:KPCR_IDR], eax + + /* Get the current IRQL and mask the IRQs in the PIC */ + movzx eax, byte ptr [fs:KPCR_IRQL] + mov eax, _KiI8259MaskTable[eax*4] + or eax, [fs:KPCR_IDR] + out 0x21, al + shr eax, 8 + out 0xA1, al + + /* Enable interrupts and return TRUE */ + sti + mov eax, 1 + ret 12 + +Invalid: + + /* Fail, invalid IRQ */ + xor eax, eax + ret 12 +.endfunc + +.globl _HalBeginSystemInterrupt@12 +.func HalBeginSystemInterrupt@12 +_HalBeginSystemInterrupt@12: + + /* Convert to vector and call the handler */ + movzx ebx, byte ptr [esp+8] + sub ebx, PRIMARY_VECTOR_BASE + jmp HalpSysIntHandler[ebx*4] + +IRQ15: + + /* This is IRQ 15, check if it's spurious */ + mov al, 0xB + out 0xA0, al + in al, 0xA0 + test al, 0x80 + jnz GenericIRQ + + /* Cascaded interrupt... dismiss it and return FALSE */ + mov al, 0x62 + out 0x20, al + mov eax, 0 + ret 12 + +IRQ7: + + /* This is IRQ 7, check if it's spurious */ + mov al, 0xB + out 0x20, al + in al, 0x20 + test al, 0x80 + jnz GenericIRQ + + /* It is, return FALSE */ + mov eax, 0 + ret 12 + +GenericIRQ: + + /* Return the current IRQL */ + mov eax, [esp+12] + movzx ecx, word ptr [fs:KPCR_IRQL] + mov [eax], cl + + /* Set the new IRQL */ + movzx eax, byte ptr [esp+4] + mov [fs:KPCR_IRQL], al + + /* Set IRQ mask in the PIC */ + mov eax, _KiI8259MaskTable[eax*4] + or eax, [fs:KPCR_IDR] + out 0x21, al + shr eax, 8 + out 0xA1, al + + /* Check to which PIC the EOI was sent */ + mov eax, ebx + cmp eax, 8 + jnb Pic1 + + /* Write mask to master PIC */ + or al, 0x60 + out 0x20, al + jmp DoneBegin + +Pic1: + /* Write mask to slave PIC */ + mov al, 0x20 + out 0xA0, al + mov al, 0x62 + out 0x20, al + +DoneBegin: + + /* Enable interrupts and return TRUE */ + in al, 0x21 + sti + mov eax, 1 + ret 12 +.endfunc + +.globl _HalEndSystemInterrupt@8 +.func HalEndSystemInterrupt@8 +_HalEndSystemInterrupt@8: + + /* Get the IRQL and check if it's a software interrupt */ + movzx ecx, byte ptr [esp+4] + cmp byte ptr [fs:KPCR_IRQL], DISPATCH_LEVEL + jbe SkipMask2 + + /* Hardware interrupt, mask the appropriate IRQs in the PIC */ + mov eax, _KiI8259MaskTable[ecx*4] + or eax, [fs:KPCR_IDR] + out 0x21, al + shr eax, 8 + out 0xA1, al + +SkipMask2: + + /* Set IRQL and check if there are pending software interrupts */ + mov [fs:KPCR_IRQL], cl + mov eax, [fs:KPCR_IDR] + mov al, SoftIntByteTable[eax] + cmp al, cl + ja DoCall + ret 8 + +DoCall: + + /* There are pending softwate interrupts, call their handlers */ + add esp, 8 + jmp SoftIntHandlerTable2[eax*4] +.endfunc + +.globl @KfLowerIrql@4 +.func @KfLowerIrql@4 +_@KfLowerIrql@4: +@KfLowerIrql@4: + + /* Save flags since we'll disable interrupts */ + pushf + + /* Disable interrupts and check if IRQL is below DISPATCH_LEVEL */ + movzx ecx, cl + cmp byte ptr [fs:KPCR_IRQL], DISPATCH_LEVEL + cli + jbe SkipMask + + /* Clear interrupt masks since there's a pending hardware interrupt */ + mov eax, _KiI8259MaskTable[ecx*4] + or eax, [fs:KPCR_IDR] + out 0x21, al + shr eax, 8 + out 0xA1, al + +SkipMask: + + /* Set the new IRQL and check if there's a pending software interrupt */ + mov [fs:KPCR_IRQL], cl + mov eax, [fs:KPCR_IDR] + mov al, SoftIntByteTable[eax] + cmp al, cl + jbe AfterCall2 + + /* There is, call it */ + call SoftIntHandlerTable[eax*4] + +AfterCall2: + + /* Restore interrupts and return */ + popf + ret +.endfunc +#endif + +.globl @KfRaiseIrql@4 +.func @KfRaiseIrql@4 +_@KfRaiseIrql@4: +@KfRaiseIrql@4: + + /* Get the IRQL and check if it's Software level only */ + xor eax, eax + mov al, [fs:KPCR_IRQL] + + movzx ecx, cl + cmp cl, DISPATCH_LEVEL + jbe SetIrql + + /* Save the current IRQL */ + mov edx, eax + + /* It's a hardware IRQL, so disable interrupts */ + pushf + cli + + /* Set the new IRQL */ + mov [fs:KPCR_IRQL], cl + +#if 0 + /* Mask the interrupts in the PIC */ + mov eax, _KiI8259MaskTable[ecx*4] + or eax, [fs:KPCR_IDR] + out 0x21, al + shr eax, 8 + out 0xA1, al +#endif + + /* Restore interrupts and return old IRQL */ + popf + mov eax, edx + ret + +SetIrql: + + /* Set the IRQL and return */ + mov [fs:KPCR_IRQL], cl + ret +.endfunc + +.globl _KeGetCurrentIrql@0 +.func KeGetCurrentIrql@0 +_KeGetCurrentIrql@0: + + /* Return the IRQL */ + movzx eax, word ptr [fs:KPCR_IRQL] + ret +.endfunc + +.globl _KeRaiseIrqlToDpcLevel@0 +.func KeRaiseIrqlToDpcLevel@0 +_KeRaiseIrqlToDpcLevel@0: + + /* Get the current IRQL */ + xor eax, eax + mov al, [fs:KPCR_IRQL] + + /* Set DISPATCH_LEVEL */ + mov byte ptr [fs:KPCR_IRQL], DISPATCH_LEVEL + ret +.endfunc + +.globl _KeRaiseIrqlToSynchLevel@0 +.func KeRaiseIrqlToSynchLevel@0 +_KeRaiseIrqlToSynchLevel@0: + + /* Disable interrupts */ + pushf + cli + + /* Mask out interrupts */ + mov eax, _KiI8259MaskTable + DISPATCH_LEVEL * 2 + or eax, [fs:KPCR_IDR] + out 0x21, al + shr eax, 8 + out 0xA1, al + + /* Return the old IRQL, enable interrupts and set to DISPATCH */ + mov al, [fs:KPCR_IRQL] + mov byte ptr [fs:KPCR_IRQL], DISPATCH_LEVEL + popf + ret +.endfunc + +.globl _HalpApcInterrupt +.func HalpApcInterrupt +_HalpApcInterrupt: + + /* Create fake interrupt stack */ + pop eax + pushf + push cs + push eax + + /* Enter interrupt */ + INT_PROLOG(hapc) +.endfunc + +.globl _HalpApcInterrupt2ndEntry +.func HalpApcInterrupt2ndEntry +_HalpApcInterrupt2ndEntry: + + /* Save current IRQL and set to APC level */ + push [fs:KPCR_IRQL] + mov byte ptr [fs:KPCR_IRQL], APC_LEVEL + and dword ptr [fs:KPCR_IRR], ~(1 << APC_LEVEL) + + /* Enable interrupts and check if we came from User/V86 mode */ + sti + mov eax, [ebp+KTRAP_FRAME_CS] + and eax, MODE_MASK + test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK + jz DeliverApc + + /* Set user mode delivery */ + or eax, UserMode + +DeliverApc: + + /* Deliver the APCs */ + push ebp + push 0 + push eax + call _KiDeliverApc@12 + + /* Disable interrupts and end it */ + cli + call _HalpEndSoftwareInterrupt@4 + jmp _Kei386EoiHelper@0 +.endfunc + +.globl _HalpDispatchInterrupt +.func HalpDispatchInterrupt +_HalpDispatchInterrupt: + + /* Create fake interrupt stack */ + pop eax + pushf + push cs + push eax + + /* Enter interrupt */ + INT_PROLOG(hapc) +.endfunc + +.globl _HalpDispatchInterrupt2ndEntry +.func HalpDispatchInterrupt2ndEntry +_HalpDispatchInterrupt2ndEntry: + + /* Save current IRQL and set to DPC level */ + push [fs:KPCR_IRQL] + mov byte ptr [fs:KPCR_IRQL], DISPATCH_LEVEL + and dword ptr [fs:KPCR_IRR], ~(1 << DISPATCH_LEVEL) + + /* Enable interrupts and let the kernel handle this */ + sti + call _KiDispatchInterrupt@0 + + /* Disable interrupts and end it */ + cli + call _HalpEndSoftwareInterrupt@4 + jmp _Kei386EoiHelper@0 +.endfunc + +.globl _HalpEndSoftwareInterrupt@4 +.func HalpEndSoftwareInterrupt@4 +_HalpEndSoftwareInterrupt@4: + + /* Get the IRQL and check if we're in the software region */ + movzx ecx, byte ptr [esp+4] + cmp byte ptr [fs:KPCR_IRQL], DISPATCH_LEVEL + jbe SoftwareInt + + /* Set the right mask in the PIC for the hardware IRQ */ + mov eax, _KiI8259MaskTable[ecx*4] + or eax, [fs:KPCR_IDR] + out 0x21, al + shr eax, 8 + out 0xA1, al + +SoftwareInt: + /* Check if there are pending software interrupts */ + mov [fs:KPCR_IRQL], cl + mov eax, [fs:KPCR_IDR] + mov al, SoftIntByteTable[eax] + cmp al, cl + ja DoCall2 + ret 4 + +DoCall2: + + /* There are pending softwate interrupts, call their handlers */ + add esp, 8 + jmp SoftIntHandlerTable2[eax*4] +.endfunc diff --git a/reactos/hal/halx86/generic/irql.c b/reactos/hal/halx86/generic/irql.c index e2ce37856ae..bfe645a6368 100644 --- a/reactos/hal/halx86/generic/irql.c +++ b/reactos/hal/halx86/generic/irql.c @@ -19,38 +19,16 @@ * FIXME: Use EISA_CONTROL STRUCTURE INSTEAD OF HARD-CODED OFFSETS */ -typedef union +UCHAR Table[8] = { - USHORT both; - struct - { - BYTE master; - BYTE slave; - }; -} -PIC_MASK; - -/* - * PURPOSE: - Mask for HalEnableSystemInterrupt and HalDisableSystemInterrupt - * - At startup enable timer and cascade - */ -#if defined(__GNUC__) -static PIC_MASK pic_mask = {.both = 0xFFFA}; -#else -static PIC_MASK pic_mask = { 0xFFFA }; -#endif + 0, 0, + 1, 1, + 2, 2, 2, 2 +}; +ULONG pic_mask = {0xFFFFFFFA}; -/* - * PURPOSE: Mask for disabling of acknowledged interrupts - */ -#if defined(__GNUC__) -static PIC_MASK pic_mask_intr = {.both = 0x0000}; -#else -static PIC_MASK pic_mask_intr = { 0 }; -#endif - -static ULONG HalpPendingInterruptCount[NR_IRQS]; +static ULONG HalpPendingInterruptCount[NR_IRQS] = {0}; #define DIRQL_TO_IRQ(x) (PROFILE_LEVEL - x) #define IRQ_TO_DIRQL(x) (PROFILE_LEVEL - x) @@ -60,40 +38,7 @@ KiInterruptDispatch2 (ULONG Irq, KIRQL old_level); /* FUNCTIONS ****************************************************************/ -#undef KeGetCurrentIrql -KIRQL STDCALL KeGetCurrentIrql (VOID) -/* - * PURPOSE: Returns the current irq level - * RETURNS: The current irq level - */ -{ - return(KeGetPcr()->Irql); -} - -VOID HalpInitPICs(VOID) -{ - memset(HalpPendingInterruptCount, 0, sizeof(HalpPendingInterruptCount)); - - /* Initialization sequence */ - WRITE_PORT_UCHAR((PUCHAR)0x20, 0x11); - WRITE_PORT_UCHAR((PUCHAR)0xa0, 0x11); - /* Start of hardware irqs (0x24) */ - WRITE_PORT_UCHAR((PUCHAR)0x21, IRQ_BASE); - WRITE_PORT_UCHAR((PUCHAR)0xa1, IRQ_BASE + 8); - /* 8259-1 is master */ - WRITE_PORT_UCHAR((PUCHAR)0x21, 0x4); - /* 8259-2 is slave */ - WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x2); - /* 8086 mode */ - WRITE_PORT_UCHAR((PUCHAR)0x21, 0x1); - WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x1); - /* Enable interrupts */ - WRITE_PORT_UCHAR((PUCHAR)0x21, pic_mask.master); - WRITE_PORT_UCHAR((PUCHAR)0xa1, pic_mask.slave); - - /* We can now enable interrupts */ - Ki386EnableInterrupts(); -} +extern ULONG KiI8259MaskTable[]; VOID HalpEndSystemInterrupt(KIRQL Irql) /* @@ -101,21 +46,16 @@ VOID HalpEndSystemInterrupt(KIRQL Irql) */ { ULONG flags; - const USHORT mask[] = - { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0xc000, 0xe000, 0xf000, - 0xf800, 0xfc00, 0xfe00, 0xff00, 0xff80, 0xffc0, 0xffe0, 0xfff0, - 0xfff8, 0xfffc, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - }; + ULONG Mask; /* Interrupts should be disable while enabling irqs of both pics */ Ki386SaveFlags(flags); Ki386DisableInterrupts(); - pic_mask_intr.both &= mask[Irql]; - WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.master)); - WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave)); + Mask = pic_mask | KiI8259MaskTable[Irql]; + WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)Mask); + Mask >>= 8; + WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)Mask); /* restore flags */ Ki386RestoreFlags(flags); @@ -168,9 +108,9 @@ HalpLowerIrql(KIRQL NewIrql) return; } KeGetPcr()->Irql = DISPATCH_LEVEL; - if (((PKIPCR)KeGetPcr())->HalReserved[HAL_DPC_REQUEST]) + if (Table[KeGetPcr()->IRR] >= NewIrql) { - ((PKIPCR)KeGetPcr())->HalReserved[HAL_DPC_REQUEST] = FALSE; + KeGetPcr()->IRR &= ~4; KiDispatchInterrupt(); } KeGetPcr()->Irql = APC_LEVEL; @@ -219,172 +159,36 @@ KfLowerIrql (KIRQL NewIrql) } -/********************************************************************** - * NAME EXPORTED - * KeLowerIrql - * - * DESCRIPTION - * Restores the irq level on the current processor - * - * ARGUMENTS - * NewIrql = Irql to lower to - * - * RETURN VALUE - * None - * - * NOTES - */ -#undef KeLowerIrql -VOID STDCALL -KeLowerIrql (KIRQL NewIrql) -{ - KfLowerIrql (NewIrql); -} - - -/********************************************************************** - * NAME EXPORTED - * KfRaiseIrql - * - * DESCRIPTION - * Raises the hardware priority (irql) - * - * ARGUMENTS - * NewIrql = Irql to raise to - * - * RETURN VALUE - * previous irq level - * - * NOTES - * Uses fastcall convention - */ - -KIRQL FASTCALL -KfRaiseIrql (KIRQL NewIrql) -{ - KIRQL OldIrql; - - DPRINT("KfRaiseIrql(NewIrql %d)\n", NewIrql); - - if (NewIrql < KeGetPcr()->Irql) - { - DbgPrint ("%s:%d CurrentIrql %x NewIrql %x\n", - __FILE__,__LINE__,KeGetPcr()->Irql,NewIrql); - KEBUGCHECK (0); - for(;;); - } - - OldIrql = KeGetPcr()->Irql; - KeGetPcr()->Irql = NewIrql; - return OldIrql; -} - - -/********************************************************************** - * NAME EXPORTED - * KeRaiseIrql - * - * DESCRIPTION - * Raises the hardware priority (irql) - * - * ARGUMENTS - * NewIrql = Irql to raise to - * OldIrql (OUT) = Caller supplied storage for the previous irql - * - * RETURN VALUE - * None - * - * NOTES - * Calls KfRaiseIrql - */ -#undef KeRaiseIrql -VOID STDCALL -KeRaiseIrql (KIRQL NewIrql, - PKIRQL OldIrql) -{ - *OldIrql = KfRaiseIrql (NewIrql); -} - - -/********************************************************************** - * NAME EXPORTED - * KeRaiseIrqlToDpcLevel - * - * DESCRIPTION - * Raises the hardware priority (irql) to DISPATCH level - * - * ARGUMENTS - * None - * - * RETURN VALUE - * Previous irq level - * - * NOTES - * Calls KfRaiseIrql - */ - -KIRQL STDCALL -KeRaiseIrqlToDpcLevel (VOID) -{ - return KfRaiseIrql (DISPATCH_LEVEL); -} - - -/********************************************************************** - * NAME EXPORTED - * KeRaiseIrqlToSynchLevel - * - * DESCRIPTION - * Raises the hardware priority (irql) to CLOCK2 level - * - * ARGUMENTS - * None - * - * RETURN VALUE - * Previous irq level - * - * NOTES - * Calls KfRaiseIrql - */ - -KIRQL STDCALL -KeRaiseIrqlToSynchLevel (VOID) -{ - return KfRaiseIrql (CLOCK2_LEVEL); -} - - BOOLEAN STDCALL HalBeginSystemInterrupt (KIRQL Irql, ULONG Vector, PKIRQL OldIrql) { ULONG irq; + ULONG Mask; + if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS) { return(FALSE); } irq = Vector - IRQ_BASE; - pic_mask_intr.both |= ((1 << irq) & 0xfffe); // do not disable the timer interrupt + + Mask = pic_mask | KiI8259MaskTable[Irql]; + WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)Mask); + Mask >>= 8; + WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)Mask); if (irq < 8) { - WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.master)); - WRITE_PORT_UCHAR((PUCHAR)0x20, 0x20); + WRITE_PORT_UCHAR((PUCHAR)0x20, 0x60 | irq); } else { - WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave)); /* Send EOI to the PICs */ - WRITE_PORT_UCHAR((PUCHAR)0x20,0x20); + WRITE_PORT_UCHAR((PUCHAR)0x20,0x62); WRITE_PORT_UCHAR((PUCHAR)0xa0,0x20); } - - if (KeGetPcr()->Irql >= Irql) - { - HalpPendingInterruptCount[irq]++; - return(FALSE); - } + *OldIrql = KeGetPcr()->Irql; KeGetPcr()->Irql = Irql; @@ -397,35 +201,10 @@ VOID STDCALL HalEndSystemInterrupt (KIRQL Irql, ULONG Unknown2) * FUNCTION: Finish a system interrupt and restore the specified irq level. */ { + //DPRINT1("ENDING: %lx %lx\n", Irql, Unknown2); HalpLowerIrql(Irql); HalpEndSystemInterrupt(Irql); } - -BOOLEAN -STDCALL -HalDisableSystemInterrupt( - ULONG Vector, - KIRQL Irql) -{ - ULONG irq; - - if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS) - return FALSE; - - irq = Vector - IRQ_BASE; - pic_mask.both |= (1 << irq); - if (irq < 8) - { - WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.slave)); - } - else - { - WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave)); - } - - return TRUE; -} - BOOLEAN STDCALL @@ -435,42 +214,22 @@ HalEnableSystemInterrupt( KINTERRUPT_MODE InterruptMode) { ULONG irq; + ULONG Mask; if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS) return FALSE; irq = Vector - IRQ_BASE; - pic_mask.both &= ~(1 << irq); - if (irq < 8) - { - WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.master)); - } - else - { - WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave)); - } + pic_mask &= ~(1 << irq); + + Mask = pic_mask | KiI8259MaskTable[KeGetPcr()->Irql]; + WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)Mask); + Mask >>= 8; + WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)Mask); return TRUE; } -VOID FASTCALL -HalRequestSoftwareInterrupt( - IN KIRQL Request) -{ - switch (Request) - { - case APC_LEVEL: - ((PKIPCR)KeGetPcr())->HalReserved[HAL_APC_REQUEST] = TRUE; - break; - - case DISPATCH_LEVEL: - ((PKIPCR)KeGetPcr())->HalReserved[HAL_DPC_REQUEST] = TRUE; - break; - - default: - KEBUGCHECK(0); - } -} /* EOF */ diff --git a/reactos/hal/halx86/generic/spinlock.c b/reactos/hal/halx86/generic/spinlock.c index 432ca1fb9b1..30d66bb230b 100644 --- a/reactos/hal/halx86/generic/spinlock.c +++ b/reactos/hal/halx86/generic/spinlock.c @@ -14,9 +14,34 @@ #undef KeAcquireSpinLock #undef KeReleaseSpinLock +#undef KeLowerIrql +#undef KeRaiseIrql /* FUNCTIONS ***************************************************************/ +/* + * @implemented + */ +VOID +NTAPI +KeLowerIrql(KIRQL NewIrql) +{ + /* Call the fastcall function */ + KfLowerIrql(NewIrql); +} + +/* + * @implemented + */ +VOID +NTAPI +KeRaiseIrql(KIRQL NewIrql, + PKIRQL OldIrql) +{ + /* Call the fastcall function */ + *OldIrql = KfRaiseIrql(NewIrql); +} + /* * @implemented */ diff --git a/reactos/hal/halx86/include/halp.h b/reactos/hal/halx86/include/halp.h index 2dded8edbb8..93ca9d670d5 100644 --- a/reactos/hal/halx86/include/halp.h +++ b/reactos/hal/halx86/include/halp.h @@ -29,7 +29,7 @@ PADAPTER_OBJECT STDCALL HalpAllocateAdapterEx(ULONG NumberOfMapRegisters,BOOLEAN VOID HalpInitBusHandlers (VOID); /* irql.c */ -VOID HalpInitPICs(VOID); +VOID NTAPI HalpInitPICs(VOID); /* udelay.c */ VOID HalpCalibrateStallExecution(VOID); diff --git a/reactos/include/ndk/asm.h b/reactos/include/ndk/asm.h index c2bc29e4971..a054815d60d 100644 --- a/reactos/include/ndk/asm.h +++ b/reactos/include/ndk/asm.h @@ -433,8 +433,9 @@ Author: // // Vector base +// ROS HACK HACK HACK // -#define PRIMARY_VECTOR_BASE 0x30 +#define PRIMARY_VECTOR_BASE 0x40 // // Kernel Feature Bits diff --git a/reactos/ntoskrnl/ex/init.c b/reactos/ntoskrnl/ex/init.c index 2e3da6baf89..4b6676f0317 100644 --- a/reactos/ntoskrnl/ex/init.c +++ b/reactos/ntoskrnl/ex/init.c @@ -260,6 +260,10 @@ ExecuteRuntimeAsserts(VOID) ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME, orig_ebp) == TF_ORIG_EBP); ASSERT(FIELD_OFFSET(KPCR, Tib.ExceptionList) == KPCR_EXCEPTION_LIST); ASSERT(FIELD_OFFSET(KPCR, Self) == KPCR_SELF); + ASSERT(FIELD_OFFSET(KPCR, IRR) == KPCR_IRR); + ASSERT(KeGetPcr()->IRR == 0); + ASSERT(FIELD_OFFSET(KPCR, IDR) == KPCR_IDR); + ASSERT(FIELD_OFFSET(KPCR, Irql) == KPCR_IRQL); ASSERT(FIELD_OFFSET(KIPCR, PrcbData) + FIELD_OFFSET(KPRCB, CurrentThread) == KPCR_CURRENT_THREAD); ASSERT(FIELD_OFFSET(KIPCR, PrcbData) + FIELD_OFFSET(KPRCB, NpxThread) == KPCR_NPX_THREAD); ASSERT(FIELD_OFFSET(KTSS, Esp0) == KTSS_ESP0);