Author: ros-arm-bringup Date: Tue Jul 8 04:11:44 2008 New Revision: 34366
URL: http://svn.reactos.org/svn/reactos?rev=34366&view=rev Log: - Rewrite the low-level trap/exception/system call code from the ground up: - Do not corrupt the stack anymore - Use a consistent trap frame layout (enable OldIrql and PreviousMode, and set the 0xBADB0D00 debug mark) - Use slower but more correct trap prolog/epilog code for now. - Generalize all prolog/epilog code into macros just like on x86. As a result, traps are now 6 lines of code. - Rewrite the system call interface from the ground up: - System calls didn't actually work: a debug print made the stack layout magical enough so that they didn't normally crush, but only slowly ate the stack. - Copying arguments from caller to system call was, as the comment on the original code so aptly put it, "total shit". - Due to ABI concerns, and to provide an actual template on how you're -supposed- to implement something like system calls on RISC processors, we now use a model similar to BSD, but about ten times better (with that much less code too). We'll document it later on the RosPSG Wiki. - This code probably contains some of the most vile-yet-elegant macro magic ever written for such low-level code as system call dispatching. - The result of all this is that we're at the same place as before (RamdiskAddDevice needs to be implemented by the Ramdisk guys) but with a sane low-level backend that isn't slowly eating away the stack, corrupting data, and basically working through random chance. - Move timebase code from stubs.c to its own file, time.c. - Silence multiple debug prints and fix a corrupted debug print in KiSystemStartup.
Added: trunk/reactos/ntoskrnl/ke/arm/ke_i.h (with props) trunk/reactos/ntoskrnl/ke/arm/time.c (with props) trunk/reactos/ntoskrnl/ke/arm/usercall.c (with props) Modified: trunk/reactos/hal/halarm/generic/hal.c trunk/reactos/include/ndk/arm/ketypes.h trunk/reactos/ntoskrnl/include/internal/arm/ksarm.h trunk/reactos/ntoskrnl/include/internal/arm/kxarm.h trunk/reactos/ntoskrnl/ke/arm/kiinit.c trunk/reactos/ntoskrnl/ke/arm/stubs.c trunk/reactos/ntoskrnl/ke/arm/trap.s trunk/reactos/ntoskrnl/ke/arm/trapc.c trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild
Modified: trunk/reactos/hal/halarm/generic/hal.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halarm/generic/hal.c?re... ============================================================================== --- trunk/reactos/hal/halarm/generic/hal.c [iso-8859-1] (original) +++ trunk/reactos/hal/halarm/generic/hal.c [iso-8859-1] Tue Jul 8 04:11:44 2008 @@ -759,7 +759,6 @@ // // Force a software interrupt // - DPRINT1("[SOFTINT]: %d\n", Request); WRITE_REGISTER_ULONG(VIC_SOFT_INT, 1 << Request); }
@@ -768,9 +767,8 @@ HalClearSoftwareInterrupt(IN KIRQL Request) { // - // Force a software interrupt - // - DPRINT1("[SOFTINTC] %d\n", Request); + // Clear a software interrupt + // WRITE_REGISTER_ULONG(VIC_SOFT_INT_CLEAR, 1 << Request); }
Modified: trunk/reactos/include/ndk/arm/ketypes.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/arm/ketypes.h?r... ============================================================================== --- trunk/reactos/include/ndk/arm/ketypes.h [iso-8859-1] (original) +++ trunk/reactos/include/ndk/arm/ketypes.h [iso-8859-1] Tue Jul 8 04:11:44 2008 @@ -59,13 +59,11 @@ // typedef struct _KTRAP_FRAME { - ULONG OldIrql; - // UCHAR PreviousMode; // ULONG Fpscr; // ULONG FpExc; // ULONG S[33]; - // ULONG FpExtra[8]; - ULONG Spsr; + // ULONG FpExtra[8]; + ULONG DbgArgMark; ULONG R0; ULONG R1; ULONG R2; @@ -84,6 +82,9 @@ ULONG SvcSp; ULONG SvcLr; ULONG Pc; + ULONG Spsr; + ULONG OldIrql; + ULONG PreviousMode; } KTRAP_FRAME, *PKTRAP_FRAME;
#ifndef NTOS_MODE_USER
Modified: trunk/reactos/ntoskrnl/include/internal/arm/ksarm.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/a... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/arm/ksarm.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/arm/ksarm.h [iso-8859-1] Tue Jul 8 04:11:44 2008 @@ -42,8 +42,27 @@ /* * Trap Frame offsets */ -.equ TrR0, 0x00 -.equ TrapFrameLength, 0x144 +.equ TrDbgArgMark, 0x00 +.equ TrR0, 0x04 +.equ TrR1, 0x08 +.equ TrR2, 0x0C +.equ TrR3, 0x10 +.equ TrR4, 0x14 +.equ TrR5, 0x18 +.equ TrR6, 0x1C +.equ TrR7, 0x20 +.equ TrR8, 0x24 +.equ TrR9, 0x28 +.equ TrR10, 0x2C +.equ TrR11, 0x30 +.equ TrR12, 0x34 +.equ TrUserSp, 0x38 +.equ TrUserLr, 0x3C +.equ TrSvcSp, 0x40 +.equ TrSvcLr, 0x44 +.equ TrPc, 0x48 +.equ TrSpsr, 0x4C +.equ TrapFrameLength, (22 * 0x04)
/* * PCR
Modified: trunk/reactos/ntoskrnl/include/internal/arm/kxarm.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/a... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/arm/kxarm.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/arm/kxarm.h [iso-8859-1] Tue Jul 8 04:11:44 2008 @@ -19,3 +19,171 @@ end_&Name: .endfunc .endm + +.macro TRAP_PROLOG Abort + // + // Fixup lr + // +.if \Abort + sub lr, lr, #8 +.else + sub lr, lr, #4 +.endif + + // + // Save the bottom 4 registers + // + stmdb sp, {r0-r3} + + // + // Save the abort lr, sp, spsr, cpsr + // + mov r0, lr + mov r1, sp + mrs r2, cpsr + mrs r3, spsr + + // + // Switch to SVC mode + // + bic r2, r2, #CPSR_MODES + orr r2, r2, #CPSR_SVC_MODE + msr cpsr_c, r2 + + // + // Save the SVC sp before we modify it + // + mov r2, sp + + // + // Make space for the trap frame + // + sub sp, sp, #TrapFrameLength + + // + // Save abt32 state + // + str r0, [sp, #TrPc] + str lr, [sp, #TrSvcLr] + str r2, [sp, #TrSvcSp] + + // + // Restore the saved SPSR + // + msr spsr_all, r3 + + // + // Restore our 4 registers + // + ldmdb r1, {r0-r3} + + // + // Build trap frame + // FIXME: Change to stmdb later + // + str r0, [sp, #TrR0] + str r1, [sp, #TrR1] + str r2, [sp, #TrR2] + str r3, [sp, #TrR3] + str r4, [sp, #TrR4] + str r5, [sp, #TrR5] + str r6, [sp, #TrR6] + str r7, [sp, #TrR7] + str r8, [sp, #TrR8] + str r9, [sp, #TrR9] + str r10, [sp, #TrR10] + str r11, [sp, #TrR11] + str r12, [sp, #TrR12] + mov r12, sp + add r12, r12, #TrUserSp + stm r12, {sp, lr}^ + mrs r0, spsr_all + str r0, [sp, #TrSpsr] + ldr r0, =0xBADB0D00 + str r0, [sp, #TrDbgArgMark] +.endm + +.macro SYSCALL_PROLOG + // + // Make space for the trap frame + // + sub sp, sp, #TrapFrameLength + + // + // Build trap frame + // FIXME: Change to stmdb later + // + str r0, [sp, #TrR0] + str r1, [sp, #TrR1] + str r2, [sp, #TrR2] + str r3, [sp, #TrR3] + str r4, [sp, #TrR4] + str r5, [sp, #TrR5] + str r6, [sp, #TrR6] + str r7, [sp, #TrR7] + str r8, [sp, #TrR8] + str r9, [sp, #TrR9] + str r10, [sp, #TrR10] + str r11, [sp, #TrR11] + str r12, [sp, #TrR12] + mov r12, sp + add r12, r12, #TrUserSp + stm r12, {sp, lr}^ + str sp, [sp, #TrSvcSp] + str lr, [sp, #TrPc] + mrs r0, spsr_all + str r0, [sp, #TrSpsr] + ldr r0, =0xBADB0D00 + str r0, [sp, #TrDbgArgMark] +.endm + +.macro TRAP_EPILOG SystemCall + // + // ASSERT(TrapFrame->DbgArgMark == 0xBADB0D00) + // + ldr r0, [sp, #TrDbgArgMark] + ldr r1, =0xBADB0D00 + cmp r0, r1 + bne 1f + + // + // Get the SPSR and restore it + // + ldr r0, [sp, #TrSpsr] + msr spsr_all, r0 + + // + // Restore the registers + // FIXME: Use LDMIA later + // + mov r0, sp + add r0, r0, #TrUserSp + ldm r0, {sp, lr}^ + ldr r0, [sp, #TrR0] + ldr r1, [sp, #TrR1] + ldr r2, [sp, #TrR2] + ldr r3, [sp, #TrR3] + ldr r4, [sp, #TrR4] + ldr r5, [sp, #TrR5] + ldr r6, [sp, #TrR6] + ldr r7, [sp, #TrR7] + ldr r8, [sp, #TrR8] + ldr r9, [sp, #TrR9] + ldr r10, [sp, #TrR10] + ldr r11, [sp, #TrR11] + ldr r12, [sp, #TrR12] + + // + // Restore program execution state + // +.if \SystemCall + ldr lr, [sp, #TrPc] + add sp, sp, #TrapFrameLength + movs pc, lr +.else + add sp, sp, #TrSvcSp + ldmia sp, {sp, lr, pc}^ +.endif +1: + b . +.endm
Added: trunk/reactos/ntoskrnl/ke/arm/ke_i.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/arm/ke_i.h?rev=... ============================================================================== --- trunk/reactos/ntoskrnl/ke/arm/ke_i.h (added) +++ trunk/reactos/ntoskrnl/ke/arm/ke_i.h [iso-8859-1] Tue Jul 8 04:11:44 2008 @@ -1,0 +1,104 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: ntoskrnl/ke/arm/ke_i.h + * PURPOSE: Implements macro-generated system call portable wrappers + * PROGRAMMERS: ReactOS Portable Systems Group + */ + +// +// First, cleanup after any previous invocation +// +#undef _1 +#undef _2 +#undef _3 +#undef _4 +#undef _5 +#undef _6 +#undef _7 +#undef _8 +#undef _9 +#undef a +#undef b +#undef c +#undef d +#undef e +#undef f +#undef _10 +#undef _11 +#undef SYSCALL + +// +// Are we building the typedef prototypes? +// +#ifdef PROTO + // + // Then, each parameter is actually a prototype argument + // + #define _1 PVOID + #define _2 PVOID + #define _3 PVOID + #define _4 PVOID + #define _5 PVOID + #define _6 PVOID + #define _7 PVOID + #define _8 PVOID + #define _9 PVOID + #define a PVOID + #define b PVOID + #define c PVOID + #define d PVOID + #define e PVOID + #define f PVOID + #define _10 PVOID + #define _11 PVOID + + // + // And we generate the typedef + // + #define SYSCALL(x, y) typedef NTSTATUS (*PKI_SYSCALL_##x##PARAM)y; + + // + // Cleanup for next run + // + #undef PROTO +#else + // + // Each parameter is actually an argument for the system call + // + #define _1 g[0x00] + #define _2 g[0x01] + #define _3 g[0x02] + #define _4 g[0x03] + #define _5 g[0x04] + #define _6 g[0x05] + #define _7 g[0x06] + #define _8 g[0x07] + #define _9 g[0x08] + #define a g[0x09] + #define b g[0x0A] + #define c g[0x0B] + #define d g[0x0C] + #define e g[0x0D] + #define f g[0x0E] + #define _10 g[0x0F] + #define _11 g[0x10] + + // + // And we generate the actual system call + // + #define SYSCALL(x, y) \ + NTSTATUS \ + KiSyscall##x##Param( \ + IN PVOID p, \ + IN PVOID *g \ + ) \ + { \ + return ((PKI_SYSCALL_##x##PARAM)p)y; \ + } + + // + // Cleanup for next run + // + #undef FUNC +#endif
Propchange: trunk/reactos/ntoskrnl/ke/arm/ke_i.h ------------------------------------------------------------------------------ svn:eol-style = native
Propchange: trunk/reactos/ntoskrnl/ke/arm/ke_i.h ------------------------------------------------------------------------------ svn:mime-type = text/plain
Modified: trunk/reactos/ntoskrnl/ke/arm/kiinit.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/arm/kiinit.c?re... ============================================================================== --- trunk/reactos/ntoskrnl/ke/arm/kiinit.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/arm/kiinit.c [iso-8859-1] Tue Jul 8 04:11:44 2008 @@ -80,7 +80,7 @@ PKPCR Pcr; ULONG i; DPRINT1("[INIT] Process: %p Thread: %p Stack: %p PRCB: %p Number: %d LoaderBlock: %p\n", - __FUNCTION__, InitProcess, InitThread, IdleStack, Prcb, Number, LoaderBlock); + InitProcess, InitThread, IdleStack, Prcb, Number, LoaderBlock);
// // Initialize the platform
Modified: trunk/reactos/ntoskrnl/ke/arm/stubs.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/arm/stubs.c?rev... ============================================================================== --- trunk/reactos/ntoskrnl/ke/arm/stubs.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/arm/stubs.c [iso-8859-1] Tue Jul 8 04:11:44 2008 @@ -9,284 +9,3 @@ ULONG KeProcessorLevel; ULONG KeProcessorRevision; ULONG KeFeatureBits; - - -extern LONG KiTickOffset; -extern ULONG KeTimeAdjustment; - -ULONG -KiComputeTimerTableIndex(IN LONGLONG DueTime) -{ - ULONG Hand; - DPRINT1("DueTime: %I64x Max: %lx\n", DueTime, KeMaximumIncrement); - - // - // Compute the timer table index - // - Hand = (DueTime / KeMaximumIncrement); - DPRINT1("HAND: %lx\n", Hand); - Hand %= TIMER_TABLE_SIZE; - DPRINT1("HAND: %lx\n", Hand); - return Hand; -} - -VOID -NTAPI -KeUpdateSystemTime(IN PKTRAP_FRAME TrapFrame, - IN KIRQL Irql, - IN ULONG Increment) -{ - PKPRCB Prcb = KeGetPcr()->Prcb; - ULARGE_INTEGER SystemTime, InterruptTime; - ULONG Hand; - - // - // Do nothing if this tick is being skipped - // - if (Prcb->SkipTick) - { - // - // Handle it next time - // - Prcb->SkipTick = FALSE; - return; - } - - // - // Add the increment time to the shared data - // - InterruptTime.HighPart = SharedUserData->InterruptTime.High1Time; - InterruptTime.LowPart = SharedUserData->InterruptTime.LowPart; - InterruptTime.QuadPart += Increment; - SharedUserData->InterruptTime.High1Time = InterruptTime.HighPart; - SharedUserData->InterruptTime.LowPart = InterruptTime.LowPart; - SharedUserData->InterruptTime.High2Time = InterruptTime.HighPart; - - // - // Update tick count - // - KiTickOffset -= Increment; - - // - // Check for incomplete tick - // - if (KiTickOffset <= 0) - { - // - // Update the system time - // - SystemTime.HighPart = SharedUserData->SystemTime.High1Time; - SystemTime.LowPart = SharedUserData->SystemTime.LowPart; - SystemTime.QuadPart += KeTimeAdjustment; - SharedUserData->SystemTime.High1Time = SystemTime.HighPart; - SharedUserData->SystemTime.LowPart = SystemTime.LowPart; - SharedUserData->SystemTime.High2Time = SystemTime.HighPart; - - // - // Update the tick count - // - SystemTime.HighPart = KeTickCount.High1Time; - SystemTime.LowPart = KeTickCount.LowPart; - SystemTime.QuadPart += 1; - KeTickCount.High1Time = SystemTime.HighPart; - KeTickCount.LowPart = SystemTime.LowPart; - KeTickCount.High2Time = SystemTime.HighPart; - - // - // Update it in the shared user data - // - SharedUserData->TickCount.High1Time = SystemTime.HighPart; - SharedUserData->TickCount.LowPart = SystemTime.LowPart; - SharedUserData->TickCount.High2Time = SystemTime.HighPart; - } - - // - // Check for timer expiration - // - Hand = KeTickCount.LowPart % TIMER_TABLE_SIZE; - if (KiTimerTableListHead[Hand].Time.QuadPart <= InterruptTime.QuadPart) - { - // - // Timer has expired! - // - DPRINT1("hand: %d\n", Hand); - DPRINT1("Interrupt time: %I64x\n", InterruptTime.QuadPart); - DPRINT1("TIMER EXPIRATION: %I64x!!!\n", KiTimerTableListHead[Hand].Time.QuadPart); - while (TRUE); - } - - // - // Check if we should request a debugger break - // - if (KdDebuggerEnabled) - { - // - // Check if we should break - // - if (KdPollBreakIn()) DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C); - } - - // - // Check if this was a full tick - // - if (KiTickOffset <= 0) - { - // - // Updare the tick offset - // - KiTickOffset += KeMaximumIncrement; - - // - // Update system runtime - // - KeUpdateRunTime(TrapFrame, CLOCK2_LEVEL); - } - else - { - // - // Increase interrupt count and exit - // - Prcb->InterruptCount++; - } -} - -VOID -NTAPI -KeUpdateRunTime(IN PKTRAP_FRAME TrapFrame, - IN KIRQL Irql) -{ - PKTHREAD Thread = KeGetCurrentThread(); - PKPROCESS Process = Thread->ApcState.Process; - PKPRCB Prcb = KeGetCurrentPrcb(); - - // - // Do nothing if this tick is being skipped - // - if (Prcb->SkipTick) - { - // - // Handle it next time - // - Prcb->SkipTick = FALSE; - return; - } - - // - // Increase interrupt count - // - Prcb->InterruptCount++; - - // - // Check if we came from user mode - // - if (0) //(TrapFrame->PreviousMode != KernelMode) - { - // - // Increase process user time - // - InterlockedIncrement((PLONG)&Process->UserTime); - Prcb->UserTime++; - Thread->UserTime++; - } - else - { - // - // See if we were in an ISR - // - if (TrapFrame->OldIrql > DISPATCH_LEVEL) - { - // - // Handle that - // - Prcb->InterruptTime++; - } - else if ((TrapFrame->OldIrql < DISPATCH_LEVEL) || - !(Prcb->DpcRoutineActive)) - { - // - // Handle being in kernel mode - // - Thread->KernelTime++; - InterlockedIncrement((PLONG)&Process->KernelTime); - } - else - { - // - // Handle being in a DPC - // - Prcb->DpcTime++; - - // - // FIXME: Handle DPC checks - // - } - } - - // - // Update DPC rates - // - Prcb->DpcRequestRate = ((Prcb->DpcData[0].DpcCount - Prcb->DpcLastCount) + - Prcb->DpcRequestRate) >> 1; - Prcb->DpcLastCount = Prcb->DpcData[0].DpcCount; - - // - // Check if the queue is large enough - // - if ((Prcb->DpcData[0].DpcQueueDepth) && !(Prcb->DpcRoutineActive)) - { - // - // Request a DPC - // - Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold; - HalRequestSoftwareInterrupt(DISPATCH_LEVEL); - - // - // Fix the maximum queue depth - // - if ((Prcb->DpcRequestRate < KiIdealDpcRate) && - (Prcb->MaximumDpcQueueDepth > 1)) - { - // - // Make it smaller - // - Prcb->MaximumDpcQueueDepth--; - } - } - else - { - // - // Check if we've reached the adjustment limit - // - if (!(--Prcb->AdjustDpcThreshold)) - { - // - // Reset it, and check the queue maximum - // - Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold; - if (KiMaximumDpcQueueDepth != Prcb->MaximumDpcQueueDepth) - { - // - // Increase it - // - Prcb->MaximumDpcQueueDepth++; - } - } - } - - // - // Decrement the thread quantum - // - Thread->Quantum -= CLOCK_QUANTUM_DECREMENT; - - // - // Check if the time expired - // - if ((Thread->Quantum <= 0) && (Thread != Prcb->IdleThread)) - { - // - // Schedule a quantum end - // - Prcb->QuantumEnd = 1; - //HalRequestSoftwareInterrupt(DISPATCH_LEVEL); - } -}
Added: trunk/reactos/ntoskrnl/ke/arm/time.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/arm/time.c?rev=... ============================================================================== --- trunk/reactos/ntoskrnl/ke/arm/time.c (added) +++ trunk/reactos/ntoskrnl/ke/arm/time.c [iso-8859-1] Tue Jul 8 04:11:44 2008 @@ -1,0 +1,295 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: ntoskrnl/ke/arm/time.c + * PURPOSE: Implements timebase functionality on ARM processors + * PROGRAMMERS: ReactOS Portable Systems Group + */ + +/* INCLUDES *******************************************************************/ + +#include <ntoskrnl.h> +#define NDEBUG +#include <debug.h> + +/* GLOBALS ********************************************************************/ + +LONG KiTickOffset; +ULONG KeTimeAdjustment; + +/* FUNCTIONS ******************************************************************/ + +ULONG +KiComputeTimerTableIndex(IN LONGLONG DueTime) +{ + ULONG Hand; + + // + // Compute the timer table index + // + Hand = (DueTime / KeMaximumIncrement); + Hand %= TIMER_TABLE_SIZE; + return Hand; +} + +VOID +NTAPI +KeUpdateSystemTime(IN PKTRAP_FRAME TrapFrame, + IN KIRQL Irql, + IN ULONG Increment) +{ + PKPRCB Prcb = KeGetPcr()->Prcb; + ULARGE_INTEGER SystemTime, InterruptTime; + ULONG Hand; + + // + // Do nothing if this tick is being skipped + // + if (Prcb->SkipTick) + { + // + // Handle it next time + // + Prcb->SkipTick = FALSE; + return; + } + + // + // Add the increment time to the shared data + // + InterruptTime.HighPart = SharedUserData->InterruptTime.High1Time; + InterruptTime.LowPart = SharedUserData->InterruptTime.LowPart; + InterruptTime.QuadPart += Increment; + SharedUserData->InterruptTime.High1Time = InterruptTime.HighPart; + SharedUserData->InterruptTime.LowPart = InterruptTime.LowPart; + SharedUserData->InterruptTime.High2Time = InterruptTime.HighPart; + + // + // Update tick count + // + KiTickOffset -= Increment; + + // + // Check for incomplete tick + // + if (KiTickOffset <= 0) + { + // + // Update the system time + // + SystemTime.HighPart = SharedUserData->SystemTime.High1Time; + SystemTime.LowPart = SharedUserData->SystemTime.LowPart; + SystemTime.QuadPart += KeTimeAdjustment; + SharedUserData->SystemTime.High1Time = SystemTime.HighPart; + SharedUserData->SystemTime.LowPart = SystemTime.LowPart; + SharedUserData->SystemTime.High2Time = SystemTime.HighPart; + + // + // Update the tick count + // + SystemTime.HighPart = KeTickCount.High1Time; + SystemTime.LowPart = KeTickCount.LowPart; + SystemTime.QuadPart += 1; + KeTickCount.High1Time = SystemTime.HighPart; + KeTickCount.LowPart = SystemTime.LowPart; + KeTickCount.High2Time = SystemTime.HighPart; + + // + // Update it in the shared user data + // + SharedUserData->TickCount.High1Time = SystemTime.HighPart; + SharedUserData->TickCount.LowPart = SystemTime.LowPart; + SharedUserData->TickCount.High2Time = SystemTime.HighPart; + } + + // + // Check for timer expiration + // + Hand = KeTickCount.LowPart % TIMER_TABLE_SIZE; + if (KiTimerTableListHead[Hand].Time.QuadPart <= InterruptTime.QuadPart) + { + // + // Timer has expired! + // + DPRINT1("hand: %d\n", Hand); + DPRINT1("Interrupt time: %I64x\n", InterruptTime.QuadPart); + DPRINT1("TIMER EXPIRATION: %I64x!!!\n", + KiTimerTableListHead[Hand].Time.QuadPart); + while (TRUE); + } + + // + // Check if we should request a debugger break + // + if (KdDebuggerEnabled) + { + // + // Check if we should break + // + if (KdPollBreakIn()) DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C); + } + + // + // Check if this was a full tick + // + if (KiTickOffset <= 0) + { + // + // Updare the tick offset + // + KiTickOffset += KeMaximumIncrement; + + // + // Update system runtime + // + KeUpdateRunTime(TrapFrame, CLOCK2_LEVEL); + } + else + { + // + // Increase interrupt count and exit + // + Prcb->InterruptCount++; + } +} + +VOID +NTAPI +KeUpdateRunTime(IN PKTRAP_FRAME TrapFrame, + IN KIRQL Irql) +{ + PKTHREAD Thread = KeGetCurrentThread(); + PKPROCESS Process = Thread->ApcState.Process; + PKPRCB Prcb = KeGetCurrentPrcb(); + + // + // Do nothing if this tick is being skipped + // + if (Prcb->SkipTick) + { + // + // Handle it next time + // + Prcb->SkipTick = FALSE; + return; + } + + // + // Increase interrupt count + // + Prcb->InterruptCount++; + + // + // Check if we came from user mode + // + if (0) //(TrapFrame->PreviousMode != KernelMode) + { + // + // Increase process user time + // + InterlockedIncrement((PLONG)&Process->UserTime); + Prcb->UserTime++; + Thread->UserTime++; + } + else + { + // + // See if we were in an ISR + // + if (TrapFrame->OldIrql > DISPATCH_LEVEL) + { + // + // Handle that + // + Prcb->InterruptTime++; + } + else if ((TrapFrame->OldIrql < DISPATCH_LEVEL) || + !(Prcb->DpcRoutineActive)) + { + // + // Handle being in kernel mode + // + Thread->KernelTime++; + InterlockedIncrement((PLONG)&Process->KernelTime); + } + else + { + // + // Handle being in a DPC + // + Prcb->DpcTime++; + + // + // FIXME: Handle DPC checks + // + } + } + + // + // Update DPC rates + // + Prcb->DpcRequestRate = ((Prcb->DpcData[0].DpcCount - Prcb->DpcLastCount) + + Prcb->DpcRequestRate) >> 1; + Prcb->DpcLastCount = Prcb->DpcData[0].DpcCount; + + // + // Check if the queue is large enough + // + if ((Prcb->DpcData[0].DpcQueueDepth) && !(Prcb->DpcRoutineActive)) + { + // + // Request a DPC + // + Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold; + HalRequestSoftwareInterrupt(DISPATCH_LEVEL); + + // + // Fix the maximum queue depth + // + if ((Prcb->DpcRequestRate < KiIdealDpcRate) && + (Prcb->MaximumDpcQueueDepth > 1)) + { + // + // Make it smaller + // + Prcb->MaximumDpcQueueDepth--; + } + } + else + { + // + // Check if we've reached the adjustment limit + // + if (!(--Prcb->AdjustDpcThreshold)) + { + // + // Reset it, and check the queue maximum + // + Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold; + if (KiMaximumDpcQueueDepth != Prcb->MaximumDpcQueueDepth) + { + // + // Increase it + // + Prcb->MaximumDpcQueueDepth++; + } + } + } + + // + // Decrement the thread quantum + // + Thread->Quantum -= CLOCK_QUANTUM_DECREMENT; + + // + // Check if the time expired + // + if ((Thread->Quantum <= 0) && (Thread != Prcb->IdleThread)) + { + // + // Schedule a quantum end + // + Prcb->QuantumEnd = 1; + //HalRequestSoftwareInterrupt(DISPATCH_LEVEL); + } +}
Propchange: trunk/reactos/ntoskrnl/ke/arm/time.c ------------------------------------------------------------------------------ svn:eol-style = native
Propchange: trunk/reactos/ntoskrnl/ke/arm/time.c ------------------------------------------------------------------------------ svn:mime-type = text/plain
Modified: trunk/reactos/ntoskrnl/ke/arm/trap.s URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/arm/trap.s?rev=... ============================================================================== --- trunk/reactos/ntoskrnl/ke/arm/trap.s [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/arm/trap.s [iso-8859-1] Tue Jul 8 04:11:44 2008 @@ -7,7 +7,7 @@ */
.title "ARM Trap Dispatching and Handling" - .include "ntoskrnl/include/internal/arm/kxarm.h" + #include "ntoskrnl/include/internal/arm/kxarm.h" .include "ntoskrnl/include/internal/arm/ksarm.h"
.global KiArmVectorTable @@ -28,7 +28,7 @@ _KiReservedJump: .word KiReservedException _KiInterruptJump: .word KiInterruptException _KiFastInterruptJump: .word KiFastInterruptException - + TEXTAREA NESTED_ENTRY KiUndefinedInstructionException PROLOG_END KiUndefinedInstructionException @@ -42,76 +42,25 @@
NESTED_ENTRY KiSoftwareInterruptException PROLOG_END KiSoftwareInterruptException - - // - // Save the current lr - // - str lr, [sp, #-4]! - - // - // Save the SVC lr and sp - // - str lr, [sp, #-4]! - str sp, [sp, #-4]!
// - // Make space for trap frame + // Handle trap entry // - sub sp, sp, #(4*15) - - // - // Save user-mode registers - // - stmia sp, {r0-r12} - add r0, sp, #(4*13) - stmia r0, {r13-r14}^ - mov r0, r0 - - // - // Save SPSR - // - mrs r0, spsr_all - str r0, [sp, #-4]! - - // - // Make space for IRQL - // - sub sp, sp, #4 + SYSCALL_PROLOG
// // Call the C handler // + adr lr, 1f mov r0, sp - bl KiSoftwareInterruptHandler - + ldr pc, =KiSoftwareInterruptHandler + +1: // - // Skip IRQL - // - add sp, sp, #(4) + // Handle trap exit + // + TRAP_EPILOG 1 // FromSystemCall
- // - // Get the SPSR and restore it - // - ldr r0, [sp], #4 - msr spsr_all, r0 - - // - // Restore the registers - // - ldmia sp, {r0-r14}^ - mov r0, r0 - - // - // Advance in the trap frame - // - add sp, sp, #(4*17) - - // - // Restore program execution state - // - ldr lr, [sp], #4 - movs pc, lr - b . ENTRY_END KiSoftwareInterruptException
NESTED_ENTRY KiPrefetchAbortException @@ -128,233 +77,47 @@ PROLOG_END KiDataAbortException
// - // Fixup lr + // Handle trap entry // - sub lr, lr, #8 + TRAP_PROLOG 1 // FromAbort
- // - // Save the bottom 4 registers - // - stmdb sp, {r0-r3} - - // - // Save the abort lr, sp, spsr, cpsr - // - mov r0, lr - mov r1, sp - mrs r2, cpsr - mrs r3, spsr - - // - // Switch to SVC mode - // - bic r2, r2, #CPSR_MODES - orr r2, r2, #CPSR_SVC_MODE - msr cpsr_c, r2 - - // - // Save the SVC sp before we modify it - // - mov r2, sp - - // - // Save the abort lr - // - str r0, [sp, #-4]! - - // - // Save the SVC lr and sp - // - str lr, [sp, #-4]! - str r2, [sp, #-4]! - - // - // Restore the saved SPSR - // - msr spsr_all, r3 - - // - // Restore our 4 registers - // - ldmdb r1, {r0-r3} - - // - // Make space for the trap frame - // - sub sp, sp, #(4*15) // TrapFrameLength - - // - // Save user-mode registers - // - stmia sp, {r0-r12} - add r0, sp, #(4*13) - stmia r0, {r13-r14}^ - mov r0, r0 - - // - // Save SPSR - // - mrs r0, spsr_all - str r0, [sp, #-4]! - - // - // Make space for IRQL - // - sub sp, sp, #4 - // // Call the C handler // - adr lr, AbortExit + adr lr, 1f mov r0, sp ldr pc, =KiDataAbortHandler
-AbortExit: +1: + // + // Handle trap exit + // + TRAP_EPILOG 0 // NotFromSystemCall
- // - // Skip IRQL - // - add sp, sp, #(4) - - // - // Get the SPSR and restore it - // - ldr r0, [sp], #4 - msr spsr_all, r0 - - // - // Restore the registers - // - ldmia sp, {r0-r14}^ - mov r0, r0 - - // - // Advance in the trap frame - // - add sp, sp, #(4*15) - - // - // Restore program execution state - // - ldmia sp, {sp, lr, pc}^ - b . ENTRY_END KiDataAbortException
NESTED_ENTRY KiInterruptException PROLOG_END KiInterruptException + + // + // Handle trap entry + // + TRAP_PROLOG 0 // NotFromAbort
- // - // Fixup lr - // - sub lr, lr, #4 - - // - // Save the bottom 4 registers - // - stmdb sp, {r0-r3} - - // - // Save the IRQ lr, sp, spsr, cpsr - // - mov r0, lr - mov r1, sp - mrs r2, cpsr - mrs r3, spsr - - // - // Switch to SVC mode - // - bic r2, r2, #CPSR_MODES - orr r2, r2, #CPSR_SVC_MODE - msr cpsr_c, r2 - - // - // Save the SVC sp before we modify it - // - mov r2, sp - - // - // Save the IRQ lr - // - str r0, [sp, #-4]! - - // - // Save the SVC lr and sp - // - str lr, [sp, #-4]! - str r2, [sp, #-4]! - - // - // Restore the saved SPSR - // - msr spsr_all, r3 - - // - // Restore our 4 registers - // - ldmdb r1, {r0-r3} - - // - // Make space for the trap frame - // - sub sp, sp, #(4*15) // TrapFrameLength - - // - // Save user-mode registers - // - stmia sp, {r0-r12} - add r0, sp, #(4*13) - stmia r0, {r13-r14}^ - mov r0, r0 - - // - // Save SPSR - // - mrs r0, spsr_all - str r0, [sp, #-4]! - - // - // Make space for IRQL - // - sub sp, sp, #4 - // // Call the C handler // - adr lr, IntExit + adr lr, 1f mov r0, sp mov r1, #0 ldr pc, =KiInterruptHandler
-IntExit: - +1: // - // Skip IRQL - // - add sp, sp, #(4) - - // - // Get the SPSR and restore it - // - ldr r0, [sp], #4 - msr spsr_all, r0 + // Handle trap exit + // + TRAP_EPILOG 0 // NotFromSystemCall
- // - // Restore the registers - // - ldmia sp, {r0-r14}^ - mov r0, r0 - - // - // Advance in the trap frame - // - add sp, sp, #(4*15) - - // - // Restore program execution state - // - ldmia sp, {sp, lr, pc}^ - b . ENTRY_END KiInterruptException
NESTED_ENTRY KiFastInterruptException @@ -377,85 +140,3 @@ b .
ENTRY_END KiReservedException - - - NESTED_ENTRY KiSystemCall - PROLOG_END KiSystemCall - - // - // a1 has the function pointer, a2 has an array of arguments, a3 has the count - // Save these to better locations - // - mov r4, a1 - mov r5, a2 - mov r6, a3 - - // - // Load up A1-A4 from the argument array - // It doesn't matter if we had less than 4 arguments, we'll be loading some - // of the registers with garbage, but nobody will know/care. - // - ldmia r5, {a1-a4} - add r5, r5, #(4* 4) - - // - // - // This code is complete shit. - // - // - - // - // Save stack address and return address - // - mov r11, sp - mov r10, lr - - // - // Check if we have more than 4 arguments - // - cmp r6, #4 - ble SysCall - - // - // Make space on stack - // - sub r6, r6, #4 - sub sp, sp, r6, lsl #2 - -CopyLoop: - // - // Copy one parameter - // - ldr r7, [r5] - str r7, [sp] - add r5, r5, #4 - add sp, sp, #4 - - // - // Keep looping until we've copied them all - // - cmp sp, r11 - bne CopyLoop - - // - // Set the stack - // - sub sp, sp, r6, lsl #2 - - // - // Now do the system call - // -SysCall: - mov lr, pc - mov pc, r4 - - // - // Restore the stack - // - mov sp, r11 - - // - // Get us back - // - mov pc, r10 - ENTRY_END KiSystemCall
Modified: trunk/reactos/ntoskrnl/ke/arm/trapc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/arm/trapc.c?rev... ============================================================================== --- trunk/reactos/ntoskrnl/ke/arm/trapc.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/arm/trapc.c [iso-8859-1] Tue Jul 8 04:11:44 2008 @@ -18,13 +18,6 @@ #define KiGetPreviousMode(tf) \ ((tf->Spsr & CPSR_MODES) == CPSR_USER_MODE) ? UserMode: KernelMode
-NTSTATUS -KiSystemCall( - IN PVOID Handler, - IN PULONG Arguments, - IN ULONG ArgumentCount -); - VOID FASTCALL KiRetireDpcList( @@ -35,6 +28,13 @@ FASTCALL KiQuantumEnd( VOID +); + +VOID +KiSystemService( + IN PKTHREAD Thread, + IN PKTRAP_FRAME TrapFrame, + IN ULONG Instruction );
/* FUNCTIONS ******************************************************************/ @@ -237,7 +237,7 @@ KPROCESSOR_MODE PreviousMode; KEXCEPTION_FRAME ExceptionFrame; PKTRAP_FRAME TrapFrame = KeGetCurrentThread()->TrapFrame; - DPRINT1("[APC]\n"); + //DPRINT1("[APC]\n");
// // Isolate previous mode @@ -360,6 +360,7 @@ ULONG InterruptCause, InterruptMask; PKPCR Pcr; PKTRAP_FRAME OldTrapFrame; + ASSERT(TrapFrame->DbgArgMark == 0xBADB0D00);
// // Increment interrupt count @@ -424,7 +425,7 @@ // DPRINT1("[ISR RETURN]\n");
// - // Re-enable interrupts and return IRQL + // Restore IRQL and interrupts // KeLowerIrql(OldIrql); _enable(); @@ -435,6 +436,7 @@ { NTSTATUS Status; PVOID Address = (PVOID)KeArmFaultAddressRegisterGet(); + ASSERT(TrapFrame->DbgArgMark == 0xBADB0D00); DPRINT1("[ABORT] (%x) @ %p/%p/%p\n", KeArmFaultStatusRegisterGet(), Address, TrapFrame->SvcLr, TrapFrame->Pc);
@@ -456,144 +458,12 @@ }
VOID -KiSystemService(IN PKTHREAD Thread, - IN PKTRAP_FRAME TrapFrame, - IN ULONG Instruction) -{ - ULONG Id, Number, ArgumentCount, i; - PKPCR Pcr; - ULONG_PTR ServiceTable, Offset; - PKSERVICE_TABLE_DESCRIPTOR DescriptorTable; - PVOID SystemCall; - PULONG Argument; - ULONG Arguments[16]; // Maximum 20 arguments - - // - // Increase count of system calls - // - Pcr = (PKPCR)KeGetPcr(); - Pcr->Prcb->KeSystemCalls++; - - // - // Get the system call ID - // - Id = Instruction & 0xFFFFF; - DPRINT1("[SWI] (%x) %p (%d) \n", Id, Thread, Thread->PreviousMode); - - // - // Get the descriptor table - // - ServiceTable = (ULONG_PTR)Thread->ServiceTable; - Offset = ((Id >> SERVICE_TABLE_SHIFT) & SERVICE_TABLE_MASK); - ServiceTable += Offset; - DescriptorTable = (PVOID)ServiceTable; - - // - // Get the service call number and validate it - // - Number = Id & SERVICE_NUMBER_MASK; - if (Number > DescriptorTable->Limit) - { - // - // Check if this is a GUI call - // - UNIMPLEMENTED; - ASSERT(FALSE); - } - - // - // Save the function responsible for handling this system call - // - SystemCall = (PVOID)DescriptorTable->Base[Number]; - - // - // Check if this is a GUI call - // - if (Offset & SERVICE_TABLE_TEST) - { - // - // TODO - // - UNIMPLEMENTED; - ASSERT(FALSE); - } - - // - // Check how many arguments this system call takes - // - ArgumentCount = DescriptorTable->Number[Number] / 4; - ASSERT(ArgumentCount <= 20); - - // - // Copy the register-arguments first - // First four arguments are in a1, a2, a3, a4 - // - Argument = &TrapFrame->R0; - for (i = 0; (i < ArgumentCount) && (i < 4); i++) - { - // - // Copy them into the kernel stack - // - DPRINT1("Argument: %p\n", *Argument); - Arguments[i] = *Argument; - Argument++; - } - - // - // If more than four, we'll have some on the user stack - // - if (ArgumentCount > 4) - { - // - // Check where the stack is - // - if (Thread->PreviousMode == UserMode) - { - // - // FIXME: Validate the user stack - // - Argument = (PULONG)TrapFrame->UserSp; - } - else - { - // - // We were called from the kernel - // - Argument = (PULONG)TrapFrame->SvcSp; - - // - // Bias for the values we saved - // - Argument += 2; - } - - // - // Copy the rest - // - for (i = 4; i < ArgumentCount; i++) - { - // - // Copy into kernel stack - // - DPRINT1("Argument: %p\n", *Argument); - Arguments[i] = *Argument; - Argument++; - } - } - - // - // Do the system call and save result in EAX - // - TrapFrame->R0 = KiSystemCall(SystemCall, Arguments, ArgumentCount); - DPRINT1("Returned: %lx\n", TrapFrame->R0); -} - -VOID KiSoftwareInterruptHandler(IN PKTRAP_FRAME TrapFrame) { PKTHREAD Thread; KPROCESSOR_MODE PreviousMode; ULONG Instruction; + ASSERT(TrapFrame->DbgArgMark == 0xBADB0D00);
// // Get the current thread @@ -606,9 +476,9 @@ PreviousMode = KiGetPreviousMode(TrapFrame);
// - // FIXME: Save old previous mode - // - //TrapFrame->PreviousMode = PreviousMode; + // Save old previous mode + // + TrapFrame->PreviousMode = PreviousMode;
// // Save previous mode and trap frame
Added: trunk/reactos/ntoskrnl/ke/arm/usercall.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/arm/usercall.c?... ============================================================================== --- trunk/reactos/ntoskrnl/ke/arm/usercall.c (added) +++ trunk/reactos/ntoskrnl/ke/arm/usercall.c [iso-8859-1] Tue Jul 8 04:11:44 2008 @@ -1,0 +1,207 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: ntoskrnl/ke/arm/usercall.c + * PURPOSE: Implements system calls and user-mode callbacks for ARM + * PROGRAMMERS: ReactOS Portable Systems Group + */ + +/* INCLUDES *******************************************************************/ + +#include <ntoskrnl.h> +#define NDEBUG +#include <debug.h> + +/* GLOBALS ********************************************************************/ + +// +// System call wrapper generator +// +#define BUILD_SYSCALLS \ +SYSCALL(00, ()) \ +SYSCALL(01, (_1)) \ +SYSCALL(02, (_1, _2)) \ +SYSCALL(03, (_1, _2, _3)) \ +SYSCALL(04, (_1, _2, _3, _4 )) \ +SYSCALL(05, (_1, _2, _3, _4, _5)) \ +SYSCALL(06, (_1, _2, _3, _4, _5, _6)) \ +SYSCALL(07, (_1, _2, _3, _4, _5, _6, _7)) \ +SYSCALL(08, (_1, _2, _3, _4, _5, _6, _7, _8)) \ +SYSCALL(09, (_1, _2, _3, _4, _5, _6, _7, _8, _9)) \ +SYSCALL(0A, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a)) \ +SYSCALL(0B, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a, b)) \ +SYSCALL(0C, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a, b, c)) \ +SYSCALL(0D, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a, b, c, d)) \ +SYSCALL(0E, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a, b, c, d, e)) \ +SYSCALL(0F, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a, b, c, d, e, f)) \ +SYSCALL(10, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a, b, c, d, e, f, _10)) \ +SYSCALL(11, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a, b, c, d, e, f, _10, _11)) + +// +// Generate function pointer definitions +// +#define PROTO +#include "ke_i.h" +BUILD_SYSCALLS + +// +// Generate function code +// +#define FUNC +#include "ke_i.h" +BUILD_SYSCALLS + +/* SYSTEM CALL STUBS **********************************************************/ + +typedef NTSTATUS (*PKI_SYSCALL_PARAM_HANDLER)(IN PVOID p, IN PVOID *g); +PKI_SYSCALL_PARAM_HANDLER KiSyscallHandlers[0x12] = +{ + KiSyscall00Param, + KiSyscall01Param, + KiSyscall02Param, + KiSyscall03Param, + KiSyscall04Param, + KiSyscall05Param, + KiSyscall06Param, + KiSyscall07Param, + KiSyscall08Param, + KiSyscall09Param, + KiSyscall0AParam, + KiSyscall0BParam, + KiSyscall0CParam, + KiSyscall0DParam, + KiSyscall0EParam, + KiSyscall0FParam, + KiSyscall10Param, + KiSyscall11Param, +}; + +/* FUNCIONS *******************************************************************/ + +VOID +KiSystemService(IN PKTHREAD Thread, + IN PKTRAP_FRAME TrapFrame, + IN ULONG Instruction) +{ + ULONG Id, Number, ArgumentCount, i; + PKPCR Pcr; + ULONG_PTR ServiceTable, Offset; + PKSERVICE_TABLE_DESCRIPTOR DescriptorTable; + PVOID SystemCall; + PVOID* Argument; + PVOID Arguments[0x11]; // Maximum 17 arguments + ASSERT(TrapFrame->DbgArgMark == 0xBADB0D00); + + // + // Increase count of system calls + // + Pcr = (PKPCR)KeGetPcr(); + Pcr->Prcb->KeSystemCalls++; + + // + // Get the system call ID + // + Id = Instruction & 0xFFFFF; + //DPRINT1("[SWI] (%x) %p (%d) \n", Id, Thread, Thread->PreviousMode); + + // + // Get the descriptor table + // + ServiceTable = (ULONG_PTR)Thread->ServiceTable; + Offset = ((Id >> SERVICE_TABLE_SHIFT) & SERVICE_TABLE_MASK); + ServiceTable += Offset; + DescriptorTable = (PVOID)ServiceTable; + + // + // Get the service call number and validate it + // + Number = Id & SERVICE_NUMBER_MASK; + if (Number > DescriptorTable->Limit) + { + // + // Check if this is a GUI call + // + UNIMPLEMENTED; + ASSERT(FALSE); + } + + // + // Save the function responsible for handling this system call + // + SystemCall = (PVOID)DescriptorTable->Base[Number]; + + // + // Check if this is a GUI call + // + if (Offset & SERVICE_TABLE_TEST) + { + // + // TODO + // + UNIMPLEMENTED; + ASSERT(FALSE); + } + + // + // Check how many arguments this system call takes + // + ArgumentCount = DescriptorTable->Number[Number] / 4; + ASSERT(ArgumentCount <= 20); + + // + // Copy the register-arguments first + // First four arguments are in a1, a2, a3, a4 + // + Argument = (PVOID*)&TrapFrame->R0; + for (i = 0; (i < ArgumentCount) && (i < 4); i++) + { + // + // Copy them into the kernel stack + // + Arguments[i] = *Argument; + Argument++; + } + + // + // If more than four, we'll have some on the user stack + // + if (ArgumentCount > 4) + { + // + // Check where the stack is + // + if (Thread->PreviousMode == UserMode) + { + // + // FIXME: Validate the user stack + // + ASSERT(FALSE); + Argument = (PVOID*)TrapFrame->UserSp; + } + else + { + // + // We were called from the kernel + // + Argument = (PVOID*)(TrapFrame + 1); + } + + // + // Copy the rest + // + for (i = 4; i < ArgumentCount; i++) + { + // + // Copy into kernel stack + // + Arguments[i] = *Argument; + Argument++; + } + } + + // + // Do the system call and save result in EAX + // + TrapFrame->R0 = KiSyscallHandlers[ArgumentCount]((PVOID)SystemCall, + (PVOID)Arguments); +}
Propchange: trunk/reactos/ntoskrnl/ke/arm/usercall.c ------------------------------------------------------------------------------ svn:eol-style = native
Propchange: trunk/reactos/ntoskrnl/ke/arm/usercall.c ------------------------------------------------------------------------------ svn:mime-type = text/plain
Modified: trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ntoskrnl-generic.r... ============================================================================== --- trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild [iso-8859-1] Tue Jul 8 04:11:44 2008 @@ -69,8 +69,10 @@ <file>stubs_asm.s</file> <file>stubs.c</file> <file>thrdini.c</file> + <file>time.c</file> <file>trap.s</file> <file>trapc.c</file> + <file>usercall.c</file> </directory> </if> <if property="ARCH" value="powerpc">