mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
112 lines
2.5 KiB
ArmAsm
112 lines
2.5 KiB
ArmAsm
|
/******************************************************************************
|
||
|
|
||
|
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||
|
|
||
|
This file is part of Sortix.
|
||
|
|
||
|
Sortix is free software: you can redistribute it and/or modify it under the
|
||
|
terms of the GNU General Public License as published by the Free Software
|
||
|
Foundation, either version 3 of the License, or (at your option) any later
|
||
|
version.
|
||
|
|
||
|
Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
|
||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||
|
details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License along
|
||
|
with Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||
|
|
||
|
syscall.s
|
||
|
An assembly stub that acts as glue for system calls.
|
||
|
|
||
|
******************************************************************************/
|
||
|
|
||
|
.global syscall_handler
|
||
|
|
||
|
.section .text
|
||
|
.type syscall_handler, @function
|
||
|
syscall_handler:
|
||
|
cli
|
||
|
|
||
|
# Compabillity with InterruptRegisters.
|
||
|
pushl $0x0
|
||
|
pushl $0x80
|
||
|
|
||
|
# Push eax, ecx, edx, ebx, esp, ebp, esi, edi, cr2
|
||
|
pushal
|
||
|
|
||
|
# Push the user-space data segment.
|
||
|
movl %ds, %ebp
|
||
|
pushl %ebp
|
||
|
|
||
|
# Load the kernel data segment.
|
||
|
movw $0x10, %bp
|
||
|
movl %ebp, %ds
|
||
|
movl %ebp, %es
|
||
|
movl %ebp, %fs
|
||
|
movl %ebp, %gs
|
||
|
|
||
|
# Compabillity with InterruptRegisters.
|
||
|
movl %cr2, %ebp
|
||
|
pushl %ebp
|
||
|
|
||
|
# Store the state structure's pointer so the call can modify it if needed.
|
||
|
mov %esp, syscall_state_ptr
|
||
|
|
||
|
# By default, assume the system call was complete.
|
||
|
movl $0, system_was_incomplete
|
||
|
|
||
|
# Make sure the requested system call is valid.
|
||
|
cmp SYSCALL_MAX, %eax
|
||
|
jl valid_eax
|
||
|
xorl %eax, %eax
|
||
|
|
||
|
valid_eax:
|
||
|
# Read a system call function pointer.
|
||
|
xorl %ebp, %ebp
|
||
|
movl syscall_list(%ebp,%eax,4), %eax
|
||
|
|
||
|
# Give the system call function the values given by user-space.
|
||
|
pushl %esi
|
||
|
pushl %edi
|
||
|
pushl %edx
|
||
|
pushl %ecx
|
||
|
pushl %ebx
|
||
|
|
||
|
# Call the system call.
|
||
|
calll *%eax
|
||
|
|
||
|
# Clean up after the call.
|
||
|
addl $20, %esp
|
||
|
|
||
|
# Test if the system call was incomplete
|
||
|
movl system_was_incomplete, %ebx
|
||
|
testl %ebx, %ebx
|
||
|
|
||
|
# If the system call was incomplete, the value in %eax is meaningless.
|
||
|
jg return_to_userspace
|
||
|
|
||
|
# The system call was completed, so store the return value.
|
||
|
movl %eax, 36(%esp)
|
||
|
|
||
|
return_to_userspace:
|
||
|
# Compabillity with InterruptRegisters.
|
||
|
addl $4, %esp
|
||
|
|
||
|
# Restore the user-space data segment.
|
||
|
popl %ebp
|
||
|
movl %ebp, %ds
|
||
|
movl %ebp, %es
|
||
|
movl %ebp, %fs
|
||
|
movl %ebp, %gs
|
||
|
|
||
|
popal
|
||
|
|
||
|
# Compabillity with InterruptRegisters.
|
||
|
addl $8, %esp
|
||
|
|
||
|
# Return to user-space.
|
||
|
iretl
|
||
|
|