- 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.
svn path=/trunk/; revision=34366
2008-07-08 09:11:44 +00:00
|
|
|
/*
|
|
|
|
* 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
|
2008-07-21 15:55:58 +00:00
|
|
|
KIRQL OldIrql;
|
2015-05-14 22:31:58 +00:00
|
|
|
ASSERT(TrapFrame->Reserved == 0xBADB0D00);
|
|
|
|
|
- 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.
svn path=/trunk/; revision=34366
2008-07-08 09:11:44 +00:00
|
|
|
//
|
|
|
|
// Increase count of system calls
|
|
|
|
//
|
2015-05-14 22:31:58 +00:00
|
|
|
Pcr = KeGetPcr();
|
|
|
|
Pcr->CurrentPrcb->KeSystemCalls++;
|
|
|
|
|
- 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.
svn path=/trunk/; revision=34366
2008-07-08 09:11:44 +00:00
|
|
|
//
|
|
|
|
// Get the system call ID
|
|
|
|
//
|
|
|
|
Id = Instruction & 0xFFFFF;
|
|
|
|
//DPRINT1("[SWI] (%x) %p (%d) \n", Id, Thread, Thread->PreviousMode);
|
2015-05-14 22:31:58 +00:00
|
|
|
|
- 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.
svn path=/trunk/; revision=34366
2008-07-08 09:11:44 +00:00
|
|
|
//
|
|
|
|
// Get the descriptor table
|
|
|
|
//
|
|
|
|
ServiceTable = (ULONG_PTR)Thread->ServiceTable;
|
|
|
|
Offset = ((Id >> SERVICE_TABLE_SHIFT) & SERVICE_TABLE_MASK);
|
|
|
|
ServiceTable += Offset;
|
|
|
|
DescriptorTable = (PVOID)ServiceTable;
|
2015-05-14 22:31:58 +00:00
|
|
|
|
- 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.
svn path=/trunk/; revision=34366
2008-07-08 09:11:44 +00:00
|
|
|
//
|
|
|
|
// 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);
|
|
|
|
}
|
2015-05-14 22:31:58 +00:00
|
|
|
|
- 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.
svn path=/trunk/; revision=34366
2008-07-08 09:11:44 +00:00
|
|
|
//
|
|
|
|
// Save the function responsible for handling this system call
|
|
|
|
//
|
|
|
|
SystemCall = (PVOID)DescriptorTable->Base[Number];
|
2015-05-14 22:31:58 +00:00
|
|
|
|
- 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.
svn path=/trunk/; revision=34366
2008-07-08 09:11:44 +00:00
|
|
|
//
|
|
|
|
// Check if this is a GUI call
|
|
|
|
//
|
|
|
|
if (Offset & SERVICE_TABLE_TEST)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// TODO
|
|
|
|
//
|
|
|
|
UNIMPLEMENTED;
|
|
|
|
ASSERT(FALSE);
|
|
|
|
}
|
2015-05-14 22:31:58 +00:00
|
|
|
|
- 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.
svn path=/trunk/; revision=34366
2008-07-08 09:11:44 +00:00
|
|
|
//
|
|
|
|
// Check how many arguments this system call takes
|
|
|
|
//
|
|
|
|
ArgumentCount = DescriptorTable->Number[Number] / 4;
|
2008-10-21 21:02:16 +00:00
|
|
|
ASSERT(ArgumentCount <= 17);
|
2015-05-14 22:31:58 +00:00
|
|
|
|
- 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.
svn path=/trunk/; revision=34366
2008-07-08 09:11:44 +00:00
|
|
|
//
|
|
|
|
// 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++;
|
|
|
|
}
|
2015-05-14 22:31:58 +00:00
|
|
|
|
- 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.
svn path=/trunk/; revision=34366
2008-07-08 09:11:44 +00:00
|
|
|
//
|
|
|
|
// If more than four, we'll have some on the user stack
|
|
|
|
//
|
|
|
|
if (ArgumentCount > 4)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// Check where the stack is
|
|
|
|
//
|
|
|
|
if (Thread->PreviousMode == UserMode)
|
|
|
|
{
|
|
|
|
//
|
2008-07-19 06:13:10 +00:00
|
|
|
// FIXME-USER: Validate the user stack
|
- 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.
svn path=/trunk/; revision=34366
2008-07-08 09:11:44 +00:00
|
|
|
//
|
|
|
|
ASSERT(FALSE);
|
2015-05-14 22:31:58 +00:00
|
|
|
Argument = (PVOID*)TrapFrame->Sp;
|
- 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.
svn path=/trunk/; revision=34366
2008-07-08 09:11:44 +00:00
|
|
|
}
|
|
|
|
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++;
|
|
|
|
}
|
|
|
|
}
|
2015-05-14 22:31:58 +00:00
|
|
|
|
2008-07-19 06:53:03 +00:00
|
|
|
//
|
|
|
|
// We can safely enable interrupts here
|
|
|
|
//
|
|
|
|
_enable();
|
2015-05-14 22:31:58 +00:00
|
|
|
|
- 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.
svn path=/trunk/; revision=34366
2008-07-08 09:11:44 +00:00
|
|
|
//
|
|
|
|
// Do the system call and save result in EAX
|
|
|
|
//
|
|
|
|
TrapFrame->R0 = KiSyscallHandlers[ArgumentCount]((PVOID)SystemCall,
|
|
|
|
(PVOID)Arguments);
|
2015-05-14 22:31:58 +00:00
|
|
|
|
2008-07-21 15:55:58 +00:00
|
|
|
//
|
|
|
|
// Check if this was a user call
|
|
|
|
//
|
|
|
|
if (KiGetPreviousMode(TrapFrame) == UserMode)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// Make sure we didn't return at elevated IRQL
|
|
|
|
//
|
|
|
|
OldIrql = KeGetCurrentIrql();
|
|
|
|
if (OldIrql != PASSIVE_LEVEL)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// Forcibly put us in a sane state
|
|
|
|
//
|
2015-05-14 22:31:58 +00:00
|
|
|
KeGetPcr()->CurrentIrql = 0;
|
2008-07-21 15:55:58 +00:00
|
|
|
_disable();
|
2015-05-14 22:31:58 +00:00
|
|
|
|
2008-07-21 15:55:58 +00:00
|
|
|
//
|
|
|
|
// Fail
|
|
|
|
//
|
|
|
|
KeBugCheckEx(IRQL_GT_ZERO_AT_SYSTEM_SERVICE,
|
|
|
|
(ULONG_PTR)SystemCall,
|
|
|
|
OldIrql,
|
|
|
|
0,
|
|
|
|
0);
|
|
|
|
}
|
2015-05-14 22:31:58 +00:00
|
|
|
|
2008-07-21 15:55:58 +00:00
|
|
|
//
|
|
|
|
// Make sure we're not attached and that APCs are not disabled
|
|
|
|
//
|
|
|
|
if ((KeGetCurrentThread()->ApcStateIndex != CurrentApcEnvironment) ||
|
|
|
|
(KeGetCurrentThread()->CombinedApcDisable != 0))
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// Fail
|
|
|
|
//
|
|
|
|
KeBugCheckEx(APC_INDEX_MISMATCH,
|
|
|
|
(ULONG_PTR)SystemCall,
|
|
|
|
KeGetCurrentThread()->ApcStateIndex,
|
|
|
|
KeGetCurrentThread()->CombinedApcDisable,
|
|
|
|
0);
|
|
|
|
}
|
|
|
|
}
|
2015-05-14 22:31:58 +00:00
|
|
|
|
2008-07-21 15:55:58 +00:00
|
|
|
//
|
|
|
|
// Restore the old trap frame
|
|
|
|
//
|
2015-05-14 22:31:58 +00:00
|
|
|
Thread->TrapFrame = KiGetLinkedTrapFrame(TrapFrame);
|
- 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.
svn path=/trunk/; revision=34366
2008-07-08 09:11:44 +00:00
|
|
|
}
|
2008-07-31 07:06:19 +00:00
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KiInitializeUserApc(IN PKEXCEPTION_FRAME ExceptionFrame,
|
|
|
|
IN PKTRAP_FRAME TrapFrame,
|
|
|
|
IN PKNORMAL_ROUTINE NormalRoutine,
|
|
|
|
IN PVOID NormalContext,
|
|
|
|
IN PVOID SystemArgument1,
|
|
|
|
IN PVOID SystemArgument2)
|
|
|
|
{
|
2020-07-27 00:39:48 +00:00
|
|
|
CONTEXT Context = { 0 };
|
2008-07-31 07:06:19 +00:00
|
|
|
ULONG_PTR Stack;
|
|
|
|
ULONG ContextLength;
|
|
|
|
DPRINT1("User APC: %p %p %p\n", NormalContext, SystemArgument1, SystemArgument2);
|
2015-05-14 22:31:58 +00:00
|
|
|
|
2008-07-31 07:06:19 +00:00
|
|
|
//
|
|
|
|
// Build the user mode context
|
|
|
|
//
|
|
|
|
Context.ContextFlags = CONTEXT_FULL;
|
|
|
|
KeTrapFrameToContext(TrapFrame, ExceptionFrame, &Context);
|
2015-05-14 22:31:58 +00:00
|
|
|
|
2008-07-31 07:06:19 +00:00
|
|
|
//
|
|
|
|
// Setup the context on the user stack
|
|
|
|
//
|
|
|
|
ContextLength = sizeof(CONTEXT);
|
|
|
|
Stack = (ULONG_PTR)(Context.Sp & ~7) - ContextLength;
|
2015-05-14 22:31:58 +00:00
|
|
|
|
2008-07-31 07:06:19 +00:00
|
|
|
//
|
|
|
|
// Make sure the stack is valid, and copy the context
|
|
|
|
//
|
|
|
|
ProbeForWrite((PVOID)Stack, ContextLength, sizeof(QUAD));
|
|
|
|
RtlMoveMemory((PVOID)Stack, &Context, sizeof(CONTEXT));
|
|
|
|
|
|
|
|
//
|
|
|
|
// Setup the trap frame when we return to user mode
|
|
|
|
//
|
|
|
|
TrapFrame->R0 = (ULONG)NormalContext;
|
|
|
|
TrapFrame->R1 = (ULONG)SystemArgument1;
|
|
|
|
TrapFrame->R2 = (ULONG)SystemArgument2;
|
|
|
|
TrapFrame->R3 = (ULONG)NormalRoutine;
|
2015-05-14 22:31:58 +00:00
|
|
|
TrapFrame->Sp = Stack;
|
|
|
|
TrapFrame->Lr = (ULONG)KeUserApcDispatcher;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
KeUserModeCallback(IN ULONG RoutineIndex,
|
|
|
|
IN PVOID Argument,
|
|
|
|
IN ULONG ArgumentLength,
|
|
|
|
OUT PVOID *Result,
|
|
|
|
OUT PULONG ResultLength)
|
|
|
|
{
|
2015-09-01 01:45:59 +00:00
|
|
|
ASSERT(FALSE);
|
2015-05-14 22:31:58 +00:00
|
|
|
return STATUS_NOT_IMPLEMENTED;
|
2008-07-31 07:06:19 +00:00
|
|
|
}
|
2015-05-14 22:31:58 +00:00
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
KiCallUserMode(
|
|
|
|
IN PVOID *OutputBuffer,
|
|
|
|
IN PULONG OutputLength)
|
|
|
|
{
|
2015-09-01 01:45:59 +00:00
|
|
|
ASSERT(FALSE);
|
2015-05-14 22:31:58 +00:00
|
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
NtCallbackReturn(
|
|
|
|
_In_ PVOID Result,
|
|
|
|
_In_ ULONG ResultLength,
|
|
|
|
_In_ NTSTATUS CallbackStatus)
|
|
|
|
{
|
2015-09-01 01:45:59 +00:00
|
|
|
ASSERT(FALSE);
|
2015-05-14 22:31:58 +00:00
|
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|