2 * PROJECT: ReactOS Kernel
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: ntoskrnl/ke/arm/usercall.c
5 * PURPOSE: Implements system calls and user-mode callbacks for ARM
6 * PROGRAMMERS: ReactOS Portable Systems Group
9 /* INCLUDES *******************************************************************/
15 /* GLOBALS ********************************************************************/
18 // System call wrapper generator
20 #define BUILD_SYSCALLS \
23 SYSCALL(02, (_1, _2)) \
24 SYSCALL(03, (_1, _2, _3)) \
25 SYSCALL(04, (_1, _2, _3, _4 )) \
26 SYSCALL(05, (_1, _2, _3, _4, _5)) \
27 SYSCALL(06, (_1, _2, _3, _4, _5, _6)) \
28 SYSCALL(07, (_1, _2, _3, _4, _5, _6, _7)) \
29 SYSCALL(08, (_1, _2, _3, _4, _5, _6, _7, _8)) \
30 SYSCALL(09, (_1, _2, _3, _4, _5, _6, _7, _8, _9)) \
31 SYSCALL(0A, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a)) \
32 SYSCALL(0B, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a, b)) \
33 SYSCALL(0C, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a, b, c)) \
34 SYSCALL(0D, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a, b, c, d)) \
35 SYSCALL(0E, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a, b, c, d, e)) \
36 SYSCALL(0F, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a, b, c, d, e, f)) \
37 SYSCALL(10, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a, b, c, d, e, f, _10)) \
38 SYSCALL(11, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a, b, c, d, e, f, _10, _11))
41 // Generate function pointer definitions
48 // Generate function code
54 /* SYSTEM CALL STUBS **********************************************************/
56 typedef NTSTATUS (*PKI_SYSCALL_PARAM_HANDLER
)(IN PVOID p
, IN PVOID
*g
);
57 PKI_SYSCALL_PARAM_HANDLER KiSyscallHandlers
[0x12] =
79 /* FUNCIONS *******************************************************************/
82 KiSystemService(IN PKTHREAD Thread
,
83 IN PKTRAP_FRAME TrapFrame
,
86 ULONG Id
, Number
, ArgumentCount
, i
;
88 ULONG_PTR ServiceTable
, Offset
;
89 PKSERVICE_TABLE_DESCRIPTOR DescriptorTable
;
92 PVOID Arguments
[0x11]; // Maximum 17 arguments
93 ASSERT(TrapFrame
->DbgArgMark
== 0xBADB0D00);
96 // Increase count of system calls
98 Pcr
= (PKPCR
)KeGetPcr();
99 Pcr
->Prcb
->KeSystemCalls
++;
102 // Get the system call ID
104 Id
= Instruction
& 0xFFFFF;
105 //DPRINT1("[SWI] (%x) %p (%d) \n", Id, Thread, Thread->PreviousMode);
108 // Get the descriptor table
110 ServiceTable
= (ULONG_PTR
)Thread
->ServiceTable
;
111 Offset
= ((Id
>> SERVICE_TABLE_SHIFT
) & SERVICE_TABLE_MASK
);
112 ServiceTable
+= Offset
;
113 DescriptorTable
= (PVOID
)ServiceTable
;
116 // Get the service call number and validate it
118 Number
= Id
& SERVICE_NUMBER_MASK
;
119 if (Number
> DescriptorTable
->Limit
)
122 // Check if this is a GUI call
129 // Save the function responsible for handling this system call
131 SystemCall
= (PVOID
)DescriptorTable
->Base
[Number
];
134 // Check if this is a GUI call
136 if (Offset
& SERVICE_TABLE_TEST
)
146 // Check how many arguments this system call takes
148 ArgumentCount
= DescriptorTable
->Number
[Number
] / 4;
149 ASSERT(ArgumentCount
<= 20);
152 // Copy the register-arguments first
153 // First four arguments are in a1, a2, a3, a4
155 Argument
= (PVOID
*)&TrapFrame
->R0
;
156 for (i
= 0; (i
< ArgumentCount
) && (i
< 4); i
++)
159 // Copy them into the kernel stack
161 Arguments
[i
] = *Argument
;
166 // If more than four, we'll have some on the user stack
168 if (ArgumentCount
> 4)
171 // Check where the stack is
173 if (Thread
->PreviousMode
== UserMode
)
176 // FIXME: Validate the user stack
179 Argument
= (PVOID
*)TrapFrame
->UserSp
;
184 // We were called from the kernel
186 Argument
= (PVOID
*)(TrapFrame
+ 1);
192 for (i
= 4; i
< ArgumentCount
; i
++)
195 // Copy into kernel stack
197 Arguments
[i
] = *Argument
;
203 // Do the system call and save result in EAX
205 TrapFrame
->R0
= KiSyscallHandlers
[ArgumentCount
]((PVOID
)SystemCall
,