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?r…
==============================================================================
--- 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?…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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?r…
==============================================================================
--- 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?re…
==============================================================================
--- 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?re…
==============================================================================
--- 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.…
==============================================================================
--- 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">