mirror of
https://github.com/reactos/reactos.git
synced 2024-08-19 18:02:55 +00:00
![Thomas Faber](/assets/img/avatar_default.png)
Because we can encounter pending interrupts repeatedly, HalpEndSoftwareInterrupt and HalEndSystemInterrupt already clean up the stack space for their arguments (done for CORE-11123/CORE-14076). However these functions are called from C functions such as KiInterruptDispatch and HalpDispatchInterrupt2[ndEntry]. These callers also use up stack space, and it is unknown how much. To fix this, we simply reset the stack pointer to the location of the trap frame, which is where it points during a first-level dispatch. This cleans up the stack usage of any callers higher up, and is okay because a return will happen through the trap frame anyway. Dedicated to Pierre.
84 lines
2.2 KiB
ArmAsm
84 lines
2.2 KiB
ArmAsm
/*
|
|
* FILE: hal/halx86/up/pic.S
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PURPOSE: HAL PIC Management and Control Code
|
|
* PROGRAMMER: Thomas Faber (thomas.faber@reactos.org)
|
|
*/
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
#include <asm.inc>
|
|
|
|
#include <ks386.inc>
|
|
|
|
/* GLOBALS *******************************************************************/
|
|
|
|
.data
|
|
ASSUME CS:NOTHING, DS:NOTHING, ES:NOTHING, FS:NOTHING, GS:NOTHING
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
.code
|
|
|
|
MACRO(DEFINE_END_INTERRUPT_WRAPPER, WrapperName, HandlerName)
|
|
EXTERN @&HandlerName&@8:PROC
|
|
PUBLIC _&WrapperName&@8
|
|
.PROC _&WrapperName&@8
|
|
FPO 0, 2, 0, 0, 0, FRAME_FPO
|
|
|
|
/* Call the C function with the same arguments we got */
|
|
mov ecx, [esp+4]
|
|
mov edx, [esp+8]
|
|
call @&HandlerName&@8
|
|
|
|
/* Check if we got a pointer back */
|
|
test eax, eax
|
|
jnz WrapperName&_CallIntHandler
|
|
|
|
/* No? Just return */
|
|
ret 8
|
|
|
|
WrapperName&_CallIntHandler:
|
|
/* We got a pointer to call. Since it won't return, reset the stack to
|
|
the location of the stack frame. This frees up our own stack as well
|
|
as that of the functions above us, and avoids an overflow due to
|
|
excessive recursion.
|
|
The next function takes the trap frame as its (fastcall) argument. */
|
|
mov ecx, [esp+8]
|
|
mov esp, ecx
|
|
mov ebp, esp
|
|
jmp eax
|
|
.ENDP
|
|
ENDM
|
|
|
|
MACRO(DEFINE_INTERRUPT_WRAPPER, WrapperName, HandlerName)
|
|
EXTERN _&HandlerName:PROC
|
|
PUBLIC _&WrapperName
|
|
.PROC _&WrapperName
|
|
FPO 0, 0, 0, 0, 0, FRAME_FPO
|
|
|
|
/* Call the C function */
|
|
call _&HandlerName
|
|
|
|
/* Check if we got a pointer back */
|
|
test eax, eax
|
|
jnz WrapperName&_CallIntHandler
|
|
|
|
/* No? Just return */
|
|
ret
|
|
|
|
WrapperName&_CallIntHandler:
|
|
/* Optimize the tail call to avoid stack overflow */
|
|
jmp eax
|
|
.ENDP
|
|
ENDM
|
|
|
|
|
|
DEFINE_END_INTERRUPT_WRAPPER HalpEndSoftwareInterrupt, HalpEndSoftwareInterrupt2
|
|
DEFINE_END_INTERRUPT_WRAPPER HalEndSystemInterrupt, HalEndSystemInterrupt2
|
|
|
|
DEFINE_INTERRUPT_WRAPPER HalpDispatchInterrupt, HalpDispatchInterrupt2
|
|
DEFINE_INTERRUPT_WRAPPER HalpHardwareInterruptLevel, HalpHardwareInterruptLevel2
|
|
|
|
END
|