[ros-diffs] [ros-arm-bringup] 34366: - 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.

ros-arm-bringup at svn.reactos.org ros-arm-bringup at svn.reactos.org
Tue Jul 8 11:11:45 CEST 2008


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?rev=34366&r1=34365&r2=34366&view=diff
==============================================================================
--- 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?rev=34366&r1=34365&r2=34366&view=diff
==============================================================================
--- 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/arm/ksarm.h?rev=34366&r1=34365&r2=34366&view=diff
==============================================================================
--- 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/arm/kxarm.h?rev=34366&r1=34365&r2=34366&view=diff
==============================================================================
--- 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=34366&view=auto
==============================================================================
--- 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?rev=34366&r1=34365&r2=34366&view=diff
==============================================================================
--- 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=34366&r1=34365&r2=34366&view=diff
==============================================================================
--- 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=34366&view=auto
==============================================================================
--- 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=34366&r1=34365&r2=34366&view=diff
==============================================================================
--- 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=34366&r1=34365&r2=34366&view=diff
==============================================================================
--- 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?rev=34366&view=auto
==============================================================================
--- 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.rbuild?rev=34366&r1=34365&r2=34366&view=diff
==============================================================================
--- 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">



More information about the Ros-diffs mailing list