- Finish implementing very basic system call dispatcher. Our very first system call to NtClose works properly.

- The rest of Phase 0 initialization continues smoothly, we now reach the while(TRUE) loop at the end of KiSystemStartup!
- Phase 0 bring-up is complete: The phase 1 thread should now start (once thread scheduling works).
- Next steps: IRQLs, HAL Initialization (Timers and IRQs) to get the interval clock timer running for quantum end/scheduling/time accounting.
- After that: context switching code to be able to switch to the Phase 1 thread.
- Then: Phase 1 bring-up!


svn path=/trunk/; revision=32671
This commit is contained in:
ReactOS Portable Systems Group 2008-03-12 22:06:42 +00:00
parent e4a3ca1233
commit 9901f9409a
3 changed files with 188 additions and 10 deletions

View file

@ -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 @@ AbortExit:
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)
//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

View file

@ -18,6 +18,14 @@
#define KiGetPreviousMode(tf) \
((tf->Spsr & CPSR_MODES) == CPSR_USER_MODE) ? UserMode: KernelMode
NTSTATUS
KiSystemCall(
IN PVOID Handler,
IN PULONG Arguments,
IN ULONG ArgumentCount
);
/* FUNCTIONS ******************************************************************/
NTSTATUS
@ -45,13 +53,18 @@ KiDataAbortHandler(IN PKTRAP_FRAME TrapFrame)
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 @@ KiSystemService(IN PKTHREAD Thread,
// Get the system call ID
//
Id = 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 = (ULONG_PTR)Thread->ServiceTable;
Offset = ((Id >> SERVICE_TABLE_SHIFT) & SERVICE_TABLE_MASK);
ServiceTable += Offset;
DescriptorTable = (PVOID)ServiceTable;
DPRINT1("Descriptor Table: %p (Count %d)\n", DescriptorTable, DescriptorTable->Limit);
//
// 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;
while (TRUE);
}
//
// Save the function responsible for handling this system call
//
SystemCall = (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 = DescriptorTable->Number[Number] / 4;
ASSERT(ArgumentCount <= 20);
DPRINT1("Argument Count: %d\n", ArgumentCount);
//
// 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
//
Arguments[i] = *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 = (PULONG)TrapFrame->UserSp;
for (i = 4; i < ArgumentCount; i++)
{
//
// Copy into kernel stack
//
Arguments[i] = *Argument;
Argument++;
DPRINT1("Argument %d: %x\n", i, Arguments[i]);
}
}
//
// Do the system call and save result in EAX
//
TrapFrame->R0 = KiSystemCall(SystemCall, Arguments, ArgumentCount);
}
NTSTATUS
VOID
KiSoftwareInterruptHandler(IN PKTRAP_FRAME TrapFrame)
{
PKTHREAD Thread;
@ -86,6 +191,11 @@ KiSoftwareInterruptHandler(IN PKTRAP_FRAME TrapFrame)
//
PreviousMode = KiGetPreviousMode(TrapFrame);
//
// Save old previous mode
//
//TrapFrame->PreviousMode = PreviousMode;
//
// Save previous mode and trap frame
//
@ -97,8 +207,12 @@ KiSoftwareInterruptHandler(IN PKTRAP_FRAME TrapFrame)
//
Instruction = *(PULONG)(TrapFrame->Pc - sizeof(ULONG));
//
// FIXME: Enable interrupts?
//
//
// Call the service call dispatcher
//
return KiSystemService(Thread, TrapFrame, Instruction);
KiSystemService(Thread, TrapFrame, Instruction);
}

View file

@ -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" \