- Improve system call handler by adding more debugging checks to be used later.

- Optimize and simplify trap handling by using a common exit just like on x86's Kei386EoiHelper - KiExceptionExit. This way the code isn't duplicated 6 times.
- Do the same for system calls (KiServiceExit).
- Save the previous trap frame and restore it during each system call.


svn path=/trunk/; revision=34640
This commit is contained in:
ReactOS Portable Systems Group
2008-07-21 15:55:58 +00:00
parent 3f38468f23
commit 1738564a77
4 changed files with 81 additions and 49 deletions
@@ -62,7 +62,7 @@
.equ TrSvcLr, 0x44
.equ TrPc, 0x48
.equ TrSpsr, 0x4C
.equ TrapFrameLength, (22 * 0x04)
.equ TrapFrameLength, (23 * 0x04)
/*
* Exception Frame offsets
+28 -47
View File
@@ -31,7 +31,6 @@
TEXTAREA
NESTED_ENTRY KiUndefinedInstructionException
PROLOG_END KiUndefinedInstructionException
//
// Handle trap entry
//
@@ -40,21 +39,14 @@
//
// Call the C handler
//
adr lr, 1f
ldr lr, =KiExceptionExit
mov r0, sp
ldr pc, =KiUndefinedExceptionHandler
1:
//
// Handle trap exit
//
TRAP_EPILOG 0 // NotFromSystemCall
ENTRY_END KiUndefinedInstructionException
NESTED_ENTRY KiSoftwareInterruptException
PROLOG_END KiSoftwareInterruptException
//
// Handle trap entry
//
@@ -63,21 +55,14 @@
//
// Call the C handler
//
adr lr, 1f
ldr lr, =KiServiceExit
mov r0, sp
ldr pc, =KiSoftwareInterruptHandler
1:
//
// Handle trap exit
//
TRAP_EPILOG 1 // FromSystemCall
ENTRY_END KiSoftwareInterruptException
NESTED_ENTRY KiPrefetchAbortException
PROLOG_END KiPrefetchAbortException
//
// Handle trap entry
//
@@ -86,21 +71,14 @@
//
// Call the C handler
//
adr lr, 1f
ldr lr, =KiExceptionExit
mov r0, sp
ldr pc, =KiPrefetchAbortHandler
1:
//
// Handle trap exit
//
TRAP_EPILOG 0 // NotFromSystemCall
ENTRY_END KiPrefetchAbortException
NESTED_ENTRY KiDataAbortException
PROLOG_END KiDataAbortException
//
// Handle trap entry
//
@@ -109,21 +87,14 @@
//
// Call the C handler
//
adr lr, 1f
ldr lr, =KiExceptionExit
mov r0, sp
ldr pc, =KiDataAbortHandler
1:
//
// Handle trap exit
//
TRAP_EPILOG 0 // NotFromSystemCall
ENTRY_END KiDataAbortException
NESTED_ENTRY KiInterruptException
PROLOG_END KiInterruptException
//
// Handle trap entry
//
@@ -132,25 +103,35 @@
//
// Call the C handler
//
adr lr, 1f
ldr lr, =KiExceptionExit
mov r0, sp
mov r1, #0
ldr pc, =KiInterruptHandler
1:
//
// Handle trap exit
//
TRAP_EPILOG 0 // NotFromSystemCall
ENTRY_END KiInterruptException
NESTED_ENTRY KiFastInterruptException
PROLOG_END KiFastInterruptException
//
// FIXME-PERF: Implement FIQ exception
//
b .
ENTRY_END KiFastInterruptException
NESTED_ENTRY KiExceptionExit
PROLOG_END KiExceptionExit
//
// Handle trap exit
//
TRAP_EPILOG 0 // NotFromSystemCall
ENTRY_END KiExceptionExit
NESTED_ENTRY KiServiceExit
PROLOG_END KiServiceExit
//
// Handle trap exit
//
TRAP_EPILOG 1 // FromSystemCall
ENTRY_END KiServiceExit
+1 -1
View File
@@ -457,7 +457,6 @@ KiPrefetchAbortHandler(IN PKTRAP_FRAME TrapFrame)
//
// Unhandled
//
while (TRUE);
DPRINT1("[PREFETCH ABORT] (%x) @ %p/%p/%p\n",
KeArmInstructionFaultStatusRegisterGet(), Address, TrapFrame->SvcLr, TrapFrame->Pc);
UNIMPLEMENTED;
@@ -516,6 +515,7 @@ KiSoftwareInterruptHandler(IN PKTRAP_FRAME TrapFrame)
// Save old previous mode
//
TrapFrame->PreviousMode = PreviousMode;
TrapFrame->PreviousTrapFrame = (ULONG_PTR)Thread->TrapFrame;
//
// Save previous mode and trap frame
+51
View File
@@ -9,6 +9,7 @@
/* INCLUDES *******************************************************************/
#include <ntoskrnl.h>
#include <internal/arm/ksarm.h>
#define NDEBUG
#include <debug.h>
@@ -90,6 +91,7 @@ KiSystemService(IN PKTHREAD Thread,
PVOID SystemCall;
PVOID* Argument;
PVOID Arguments[0x11]; // Maximum 17 arguments
KIRQL OldIrql;
ASSERT(TrapFrame->DbgArgMark == 0xBADB0D00);
//
@@ -209,4 +211,53 @@ KiSystemService(IN PKTHREAD Thread,
//
TrapFrame->R0 = KiSyscallHandlers[ArgumentCount]((PVOID)SystemCall,
(PVOID)Arguments);
//
// Check if this was a user call
//
if (KiGetPreviousMode(TrapFrame) == UserMode)
{
//
// Make sure we didn't return at elevated IRQL
//
OldIrql = KeGetCurrentIrql();
if (OldIrql != PASSIVE_LEVEL)
{
//
// Forcibly put us in a sane state
//
KeGetPcr()->CurrentIrql = 0;
_disable();
//
// Fail
//
KeBugCheckEx(IRQL_GT_ZERO_AT_SYSTEM_SERVICE,
(ULONG_PTR)SystemCall,
OldIrql,
0,
0);
}
//
// Make sure we're not attached and that APCs are not disabled
//
if ((KeGetCurrentThread()->ApcStateIndex != CurrentApcEnvironment) ||
(KeGetCurrentThread()->CombinedApcDisable != 0))
{
//
// Fail
//
KeBugCheckEx(APC_INDEX_MISMATCH,
(ULONG_PTR)SystemCall,
KeGetCurrentThread()->ApcStateIndex,
KeGetCurrentThread()->CombinedApcDisable,
0);
}
}
//
// Restore the old trap frame
//
Thread->TrapFrame = (PKTRAP_FRAME)TrapFrame->PreviousTrapFrame;
}