mirror of
https://github.com/reactos/reactos.git
synced 2024-06-30 01:42:30 +00:00
- 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:
parent
e4a3ca1233
commit
9901f9409a
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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" \
|
||||
|
|
Loading…
Reference in a new issue