Author: ros-arm-bringup
Date: Wed Mar 12 17:06:42 2008
New Revision: 32671
URL:
http://svn.reactos.org/svn/reactos?rev=3D32671&view=3Drev
Log:
- Finish implementing very basic system call dispatcher. Our very first sys=
tem call to NtClose works properly.
- The rest of Phase 0 initialization continues smoothly, we now reach the w=
hile(TRUE) loop at the end of KiSystemStartup!
- Phase 0 bring-up is complete: The phase 1 thread should now start (once t=
hread scheduling works).
- Next steps: IRQLs, HAL Initialization (Timers and IRQs) to get the interv=
al clock timer running for quantum end/scheduling/time accounting.
- After that: context switching code to be able to switch to the Phase 1 th=
read.
- Then: Phase 1 bring-up!
Modified:
trunk/reactos/ntoskrnl/ke/arm/trap.s
trunk/reactos/ntoskrnl/ke/arm/trapc.c
trunk/reactos/tools/nci/ncitool.c
Modified: trunk/reactos/ntoskrnl/ke/arm/trap.s
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/arm/trap.=
s?rev=3D32671&r1=3D32670&r2=3D32671&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/reactos/ntoskrnl/ke/arm/trap.s (original)
+++ trunk/reactos/ntoskrnl/ke/arm/trap.s Wed Mar 12 17:06:42 2008
@@ -72,7 +72,30 @@
//
mov r0, sp
bl KiSoftwareInterruptHandler
-
+ =
+ //
+ // 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
@@ -222,3 +245,43 @@
=
ENTRY_END KiReservedException
=
+
+ NESTED_ENTRY KiSystemCall
+ PROLOG_END KiSystemCall
+ =
+ //
+ // a1 has the function pointer, a2 has an array of arguments, a3 has t=
he 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)
+ //sub r6, r6, #4
+ =
+ //
+ // Now copy the other arguments into our stack
+ //
+CopyLoop:
+ cmp r6, #4
+ //strne sp, [r5], #4
+ //subne r6, r6, #1
+ beq .
+
+ //
+ // Now do the system call
+ //
+ mov pc, r4
+ =
+ //
+ // Should not get here
+ //
+ b .
+ 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=3D32671&r1=3D32670&r2=3D32671&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/reactos/ntoskrnl/ke/arm/trapc.c (original)
+++ trunk/reactos/ntoskrnl/ke/arm/trapc.c Wed Mar 12 17:06:42 2008
@@ -18,6 +18,14 @@
#define KiGetPreviousMode(tf) \
((tf->Spsr & CPSR_MODES) =3D=3D CPSR_USER_MODE) ? UserMode: KernelMode
=
+NTSTATUS
+KiSystemCall(
+ IN PVOID Handler,
+ IN PULONG Arguments,
+ IN ULONG ArgumentCount
+);
+ =
+
/* FUNCTIONS *************************************************************=
*****/
=
NTSTATUS
@@ -45,13 +53,18 @@
return STATUS_SUCCESS;
}
=
-NTSTATUS
+VOID
KiSystemService(IN PKTHREAD Thread,
IN PKTRAP_FRAME TrapFrame,
IN ULONG Instruction)
{
- ULONG Id;
+ 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
@@ -63,12 +76,104 @@
// Get the system call ID
//
Id =3D Instruction & 0xFFFFF;
- DPRINT1("System call (%X) from thread: %p \n", Id, Thread); =
- while (TRUE);
- return STATUS_SUCCESS;
+ DPRINT1("System call (%X) from thread: %p (%d) \n", Id, Thread, Thread=
->PreviousMode);
+ =
+ //
+ // Get the descriptor table
+ //
+ ServiceTable =3D (ULONG_PTR)Thread->ServiceTable;
+ Offset =3D ((Id >> SERVICE_TABLE_SHIFT) & SERVICE_TABLE_MASK);
+ ServiceTable +=3D Offset;
+ DescriptorTable =3D (PVOID)ServiceTable;
+ DPRINT1("Descriptor Table: %p (Count %d)\n", DescriptorTable, Descript=
orTable->Limit);
+ =
+ //
+ // Get the service call number and validate it
+ //
+ Number =3D Id & SERVICE_NUMBER_MASK;
+ if (Number > DescriptorTable->Limit)
+ {
+ //
+ // Check if this is a GUI call
+ //
+ UNIMPLEMENTED;
+ while (TRUE);
+ }
+ =
+ //
+ // Save the function responsible for handling this system call
+ //
+ SystemCall =3D (PVOID)DescriptorTable->Base[Number];
+ DPRINT1("Handler: %p\n", SystemCall);
+ DPRINT1("NtClose: %p\n", NtClose);
+ =
+ //
+ // Check if this is a GUI call
+ //
+ if (Offset & SERVICE_TABLE_TEST)
+ {
+ //
+ // TODO
+ //
+ UNIMPLEMENTED;
+ while (TRUE);
+ }
+ =
+ //
+ // Check how many arguments this system call takes
+ //
+ DPRINT1("Number: %d\n", Number);
+ ArgumentCount =3D DescriptorTable->Number[Number] / 4;
+ ASSERT(ArgumentCount <=3D 20);
+ DPRINT1("Argument Count: %d\n", ArgumentCount);
+ =
+ //
+ // Copy the register-arguments first
+ // First four arguments are in a1, a2, a3, a4
+ //
+ Argument =3D &TrapFrame->R0;
+ for (i =3D 0; (i < ArgumentCount) && (i < 4); i++)
+ {
+ //
+ // Copy them into the kernel stack
+ //
+ Arguments[i] =3D *Argument;
+ Argument++;
+ DPRINT1("Argument %d: %x\n", i, Arguments[i]);
+ }
+ =
+ //
+ // If more than four, we'll have some on the user stack
+ //
+ if (ArgumentCount > 4)
+ {
+ //
+ // FIXME: Validate the user stack
+ //
+ DPRINT1("User stack: %p\n", TrapFrame->UserSp);
+ =
+ //
+ // Copy the rest
+ //
+ Argument =3D (PULONG)TrapFrame->UserSp;
+ for (i =3D 4; i < ArgumentCount; i++)
+ {
+ //
+ // Copy into kernel stack
+ //
+ Arguments[i] =3D *Argument;
+ Argument++;
+ DPRINT1("Argument %d: %x\n", i, Arguments[i]);
+ }
+ }
+ =
+ //
+ // Do the system call and save result in EAX
+ //
+ TrapFrame->R0 =3D KiSystemCall(SystemCall, Arguments, ArgumentCount);
}
=
-NTSTATUS
+VOID
KiSoftwareInterruptHandler(IN PKTRAP_FRAME TrapFrame)
{
PKTHREAD Thread;
@@ -87,6 +192,11 @@
PreviousMode =3D KiGetPreviousMode(TrapFrame);
=
//
+ // Save old previous mode
+ //
+ //TrapFrame->PreviousMode =3D PreviousMode;
+ =
+ //
// Save previous mode and trap frame
//
Thread->TrapFrame =3D TrapFrame;
@@ -98,7 +208,11 @@
Instruction =3D *(PULONG)(TrapFrame->Pc - sizeof(ULONG));
=
//
+ // FIXME: Enable interrupts?
+ //
+ =
+ //
// Call the service call dispatcher
//
- return KiSystemService(Thread, TrapFrame, Instruction);
+ KiSystemService(Thread, TrapFrame, Instruction);
}
Modified: trunk/reactos/tools/nci/ncitool.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/nci/ncitool.c?r=
ev=3D32671&r1=3D32670&r2=3D32671&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/reactos/tools/nci/ncitool.c (original)
+++ trunk/reactos/tools/nci/ncitool.c Wed Mar 12 17:06:42 2008
@@ -100,8 +100,9 @@
#define KernelModeStub_mips " j KiSystemService\n" \
" nop\n"
=
-#define KernelModeStub_arm " swi #0x%x\n" \
- " bx lr\n\n"
+#define KernelModeStub_arm " mov ip, lr\n" \
+ " swi #0x%x\n" \
+ " bx ip\n\n"
=
#elif defined(_MSC_VER)
#define KernelModeStub_x86 " asm { \n" \