]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[linux] Add linux_syscall
authorPiotr Jaroszyński <p.jaroszynski@gmail.com>
Wed, 9 Jun 2010 18:04:09 +0000 (20:04 +0200)
committerMichael Brown <mcb30@ipxe.org>
Thu, 19 Aug 2010 11:30:03 +0000 (12:30 +0100)
Add linux_syscall for both i386 and x86_64.

Signed-off-by: Piotr Jaroszyński <p.jaroszynski@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/arch/i386/core/linux/linux_syscall.S [new file with mode: 0644]
src/arch/x86_64/core/linux/linux_syscall.S [new file with mode: 0644]

diff --git a/src/arch/i386/core/linux/linux_syscall.S b/src/arch/i386/core/linux/linux_syscall.S
new file mode 100644 (file)
index 0000000..38a3e74
--- /dev/null
@@ -0,0 +1,45 @@
+
+       .section ".data"
+       .globl linux_errno
+
+linux_errno:   .int 0
+
+       .section ".text"
+       .code32
+       .globl linux_syscall
+       .type  linux_syscall, @function
+
+linux_syscall:
+       /* Save registers */
+       pushl   %ebx
+       pushl   %esi
+       pushl   %edi
+       pushl   %ebp
+
+       movl    20(%esp), %eax  // C arg1 -> syscall number
+       movl    24(%esp), %ebx  // C arg2 -> syscall arg1
+       movl    28(%esp), %ecx  // C arg3 -> syscall arg2
+       movl    32(%esp), %edx  // C arg4 -> syscall arg3
+       movl    36(%esp), %esi  // C arg5 -> syscall arg4
+       movl    40(%esp), %edi  // C arg6 -> syscall arg5
+       movl    44(%esp), %ebp  // C arg7 -> syscall arg6
+
+       int     $0x80
+
+       /* Restore registers */
+       popl    %ebp
+       popl    %edi
+       popl    %esi
+       popl    %ebx
+
+       cmpl    $-4095, %eax
+       jae     1f
+       ret
+
+1:
+       negl    %eax
+       movl    %eax, linux_errno
+       movl    $-1, %eax
+       ret
+
+       .size linux_syscall, . - linux_syscall
diff --git a/src/arch/x86_64/core/linux/linux_syscall.S b/src/arch/x86_64/core/linux/linux_syscall.S
new file mode 100644 (file)
index 0000000..d2805f9
--- /dev/null
@@ -0,0 +1,33 @@
+
+       .section ".data"
+       .globl linux_errno
+
+linux_errno:   .int 0
+
+       .section ".text"
+       .code64
+       .globl linux_syscall
+       .type  linux_syscall, @function
+
+linux_syscall:
+       movq    %rdi, %rax    // C arg1 -> syscall number
+       movq    %rsi, %rdi    // C arg2 -> syscall arg1
+       movq    %rdx, %rsi    // C arg3 -> syscall arg2
+       movq    %rcx, %rdx    // C arg4 -> syscall arg3
+       movq    %r8, %r10     // C arg5 -> syscall arg4
+       movq    %r9, %r8      // C arg6 -> syscall arg5
+       movq    8(%rsp), %r9  // C arg7 -> syscall arg6
+
+       syscall
+
+       cmpq    $-4095, %rax
+       jae     1f
+       ret
+
+1:
+       negq    %rax
+       movl    %eax, linux_errno
+       movq    $-1, %rax
+       ret
+
+       .size linux_syscall, . - linux_syscall