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?re... ============================================================================== --- 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?re... ============================================================================== --- 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/i... ============================================================================== --- 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