Author: sir_richard
Date: Mon Jan 25 04:00:01 2010
New Revision: 45244
URL:
http://svn.reactos.org/svn/reactos?rev=45244&view=rev
Log:
[NTOS]: Split the GENERATE_TRAP_HANDLER in two separate macros. The original builds the
name of the function (and makes it global), while the TRAP_HANDLER_PROLOG is actually the
code.
[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.
Modified:
trunk/reactos/hal/halx86/generic/irq.S
trunk/reactos/hal/halx86/generic/pic.c
trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S
Modified: trunk/reactos/hal/halx86/generic/irq.S
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/generic/irq.S?r…
==============================================================================
--- trunk/reactos/hal/halx86/generic/irq.S [iso-8859-1] (original)
+++ trunk/reactos/hal/halx86/generic/irq.S [iso-8859-1] Mon Jan 25 04:00:01 2010
@@ -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
Modified: trunk/reactos/hal/halx86/generic/pic.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/generic/pic.c?r…
==============================================================================
--- trunk/reactos/hal/halx86/generic/pic.c [iso-8859-1] (original)
+++ trunk/reactos/hal/halx86/generic/pic.c [iso-8859-1] Mon Jan 25 04:00:01 2010
@@ -813,3 +813,76 @@
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);
+}
Modified: trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S [iso-8859-1] Mon Jan 25
04:00:01 2010
@@ -221,7 +221,7 @@
.endm
//
-// @name GENERATE_TRAP_HANDLER
+// @name TRAP_HANDLER_PROLOG
//
// This macro creates a kernel trap handler.
//
@@ -229,16 +229,21 @@
//
// @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 @@
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