[NTOS]: Split the GENERATE_TRAP_HANDLER in two separate macros. The original builds...
authorSir Richard <sir_richard@svn.reactos.org>
Mon, 25 Jan 2010 03:00:01 +0000 (03:00 +0000)
committerSir Richard <sir_richard@svn.reactos.org>
Mon, 25 Jan 2010 03:00:01 +0000 (03:00 +0000)
[NTOS]: Make TRAP_HANDLER_PROLOG handle software traps, in which the interrupt stack must be faked.
[NTOS]: Optimize TRAP_HANDLER_PROLOG by not pushing an error code and then making space on the stack without the error code -- just make space with the error code in the first place (nobody reads the value, so having it zero or garbage isn't important).
[HAL]:  Implement the APC and DPC software interrupt traps in C instead of ASM. Delete all contents of irq.S except the two GENERATE_TRAP_HANDLER stubs.

svn path=/trunk/; revision=45244

reactos/hal/halx86/generic/irq.S
reactos/hal/halx86/generic/pic.c
reactos/ntoskrnl/include/internal/i386/asmmacro.S

index d9f346a..705205d 100644 (file)
@@ -7,98 +7,13 @@
 
 /* INCLUDES ******************************************************************/
 
-/* Enable this (and the define in spinlock.c) to make UP HAL work for MP Kernel */
-/* #define CONFIG_SMP */
-
 #include <asm.h>
 #include <internal/i386/asmmacro.S>
 .intel_syntax noprefix
 
 /* GLOBALS *******************************************************************/
 
-_UnhandledMsg:
-    .asciz "\n\x7\x7!!! Unhandled or Unexpected Code at line: %lx!!!\n"
-
 /* FUNCTIONS *****************************************************************/
 
-.globl _HalpApcInterrupt
-.func HalpApcInterrupt
-TRAP_FIXUPS hapc_a, hapc_t, DoFixupV86, DoFixupAbios
-_HalpApcInterrupt:
-
-    /* Create fake interrupt stack */
-    pop eax
-    pushf
-    push cs
-    push eax
-
-    /* Enter interrupt */
-    INT_PROLOG hapc_a, hapc_t, DoPushFakeErrorCode
-.endfunc
-
-.globl _HalpApcInterrupt2ndEntry
-.func HalpApcInterrupt2ndEntry
-_HalpApcInterrupt2ndEntry:
-
-    /* Save current IRQL and set to APC level */
-    push PCR[KPCR_IRQL]
-    mov dword ptr PCR[KPCR_IRQL], APC_LEVEL
-    and dword ptr PCR[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
-TRAP_FIXUPS hdpc_a, hdpc_t, DoFixupV86, DoFixupAbios
-_HalpDispatchInterrupt:
-
-    /* Create fake interrupt stack */
-    pop eax
-    pushf
-    push cs
-    push eax
-
-    /* Enter interrupt */
-    INT_PROLOG hdpc_a, hdpc_t, DoPushFakeErrorCode
-.endfunc
-
-.globl _HalpDispatchInterrupt2ndEntry
-.func HalpDispatchInterrupt2ndEntry
-_HalpDispatchInterrupt2ndEntry:
-
-    /* Save current IRQL and set to DPC level */
-    push PCR[KPCR_IRQL]
-    mov dword ptr PCR[KPCR_IRQL], DISPATCH_LEVEL
-    and dword ptr PCR[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
+GENERATE_TRAP_HANDLER HalpApcInterrupt, 0, 0, 1
+GENERATE_TRAP_HANDLER HalpDispatchInterrupt, 0, 0, 1
\ No newline at end of file
index 8700758..9ea1350 100644 (file)
@@ -813,3 +813,76 @@ HalEndSystemInterrupt(IN KIRQL OldIrql,
     PendingIrql = SWInterruptLookUpTable[Pcr->IRR];
     if (PendingIrql > OldIrql) SWInterruptHandlerTable[PendingIrql]();
 }
+
+/* SOFTWARE INTERRUPT TRAPS ***************************************************/
+
+VOID
+FASTCALL
+HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
+{
+    KIRQL CurrentIrql;
+    PKPCR Pcr = KeGetPcr();
+    
+    /* Set up a fake INT Stack */
+    TrapFrame->EFlags = __readeflags();
+    TrapFrame->SegCs = KGDT_R0_CODE;
+    TrapFrame->Eip = TrapFrame->Eax;
+    
+    /* Build the trap frame */
+    KiEnterInterruptTrap(TrapFrame);
+    
+    /* Save the current IRQL and update it */
+    CurrentIrql = Pcr->Irql;
+    Pcr->Irql = APC_LEVEL;
+    
+    /* Remove DPC from IRR */
+    Pcr->IRR &= ~(1 << APC_LEVEL);
+    
+    /* Enable interrupts and call the kernel's APC interrupt handler */
+    _enable();
+    KiDeliverApc(((KiUserTrap(TrapFrame)) || (TrapFrame->EFlags & EFLAGS_V86_MASK)) ?
+                 UserMode : KernelMode,
+                 NULL,
+                 TrapFrame);
+
+    /* Disable interrupts and end the interrupt */
+    _disable();
+    HalpEndSoftwareInterrupt(CurrentIrql);
+    
+    /* Exit the interrupt */
+    KiEoiHelper(TrapFrame);
+}
+
+VOID
+FASTCALL
+HalpDispatchInterruptHandler(IN PKTRAP_FRAME TrapFrame)
+{
+    KIRQL CurrentIrql;
+    PKPCR Pcr = KeGetPcr();
+    
+    /* Set up a fake INT Stack */
+    TrapFrame->EFlags = __readeflags();
+    TrapFrame->SegCs = KGDT_R0_CODE;
+    TrapFrame->Eip = TrapFrame->Eax;
+    
+    /* Build the trap frame */
+    KiEnterInterruptTrap(TrapFrame);
+    
+    /* Save the current IRQL and update it */
+    CurrentIrql = Pcr->Irql;
+    Pcr->Irql = DISPATCH_LEVEL;
+    
+    /* Remove DPC from IRR */
+    Pcr->IRR &= ~(1 << DISPATCH_LEVEL);
+    
+    /* Enable interrupts and call the kernel's DPC interrupt handler */
+    _enable();
+    KiDispatchInterrupt();
+    
+    /* Disable interrupts and end the interrupt */
+    _disable();
+    HalpEndSoftwareInterrupt(CurrentIrql);
+    
+    /* Exit the interrupt */
+    KiEoiHelper(TrapFrame);
+}
index 60ed147..312a1f4 100644 (file)
@@ -221,7 +221,7 @@ _KiUnexpectedInterrupt&Number:
 .endm
 
 //
-// @name GENERATE_TRAP_HANDLER
+// @name TRAP_HANDLER_PROLOG
 //
 // This macro creates a kernel trap handler.
 //
@@ -229,16 +229,21 @@ _KiUnexpectedInterrupt&Number:
 //
 // @remark None.
 //
-.macro GENERATE_TRAP_HANDLER Name, ErrorCode=1, FastV86=0
-.func Name
-_&Name:
-    /* Some traps generate an error code, some don't (thanks, Intel!) */
-    .if \ErrorCode
-        push 0
+.macro TRAP_HANDLER_PROLOG ErrorCode=1, Software=0
+
+    /* What kind of trap is it */
+    .if \Software
+        /* Software traps need a fake interrupt stack */
+        pop eax
+        sub esp, KTRAP_FRAME_ESP
+    .elseif \ErrorCode
+        /* Some traps generate an error code, some don't (thanks, Intel!) */
+        sub esp, KTRAP_FRAME_EIP
+    .else
+        sub esp, KTRAP_FRAME_ERROR_CODE
     .endif
-    
+
     /* Make space for trap frame and save registers before we enter C code */
-    sub esp, KTRAP_FRAME_ERROR_CODE
     mov [esp+KTRAP_FRAME_EAX], eax
     mov [esp+KTRAP_FRAME_EBX], ebx
     mov [esp+KTRAP_FRAME_ECX], ecx
@@ -247,7 +252,22 @@ _&Name:
     mov [esp+KTRAP_FRAME_EDI], edi
     mov [esp+KTRAP_FRAME_EBP], ebp
     mov ecx, esp
-        
+.endm
+
+//
+// @name GENERATE_TRAP_HANDLER
+//
+// This macro creates a kernel trap handler.
+//
+// @param None.
+//
+// @remark None.
+//
+.macro GENERATE_TRAP_HANDLER Name, ErrorCode=1, FastV86=0, Software=0
+.globl _&Name
+.func Name
+_&Name:
+    TRAP_HANDLER_PROLOG ErrorCode, Software
     /*
      * The GPF and Invalid Opcode handlers are performance critical when talking
      * about V8086 traps, because they control the main flow of execution during