Index: src/trusted/service_runtime/arch/mips/nacl_syscall.S |
diff --git a/src/trusted/service_runtime/arch/mips/nacl_syscall.S b/src/trusted/service_runtime/arch/mips/nacl_syscall.S |
new file mode 100644 |
index 0000000000000000000000000000000000000000..bb4c89475884000053c2f35d6edde588e2100f3b |
--- /dev/null |
+++ b/src/trusted/service_runtime/arch/mips/nacl_syscall.S |
@@ -0,0 +1,131 @@ |
+/* |
+ * Copyright 2012 The Native Client Authors. All rights reserved. |
+ * Use of this source code is governed by a BSD-style license that can |
+ * be found in the LICENSE file. |
+ */ |
+ |
+#include "native_client/src/trusted/service_runtime/nacl_config.h" |
+ |
+.text |
+ |
+ |
+/* |
+ * This trusted code is linked into the service runtime. It is executed when a |
+ * nacl module performs a system call via a service runtime interface. The nacl |
+ * module jumps to the trampoline corresponding to the syscall and then here. |
+ * This code switches the execution contexts (registers and stack) from |
+ * untrusted to trusted. |
+ * |
+ * on stack: |
+ * |
+ * top |
+ * ===== |
+ * a0 - alignment for NaClSyscallCSegHook |
+ * ra - return address |
+ * arg 1 |
+ * arg 2 |
+ * ..... |
+ * arg N |
+ */ |
+ |
+DEFINE_GLOBAL_HIDDEN_IDENTIFIER(NaClSyscallSeg): |
+ |
+ .set noreorder |
+ |
+/* |
+ * The following code (next 6 instructions) does what the trampoline code should |
+ * do. It places the first 4 parameters of the system call to the stack, and on |
+ * top of that it places the return address to the user module. On Mips the |
+ * trampoline is too small for all this, so the code is moved here. |
+ * |
+ * Mips passes parameters to a callee in registers a0-a3. If there are more |
+ * than 4 parameters, the first four args are passed in registers and the rest |
+ * are placed on the stack. Regardless of the number of arguments passed, Mips |
+ * o32 ABI requires that the caller should always reserve 16 bytes on stack that |
+ * correspond to registers a0-a3. |
+ * |
+ * This code pushes all parameters from registers into the stack; thus, we keep |
+ * all parameters on the stack as follows: |
+ * top - arg0, arg1, arg2, arg3 .... argN |
+ * |
+ * On top of that we push the return address, so we will know where to return |
+ * after the system call. |
+ * |
+ * After this code the stack layout must look like: |
+ * |
+ * sp+0: retaddr to user module |
+ * sp+4: arg0 (system call argument) |
+ * sp+8: arg1 |
+ * .......... |
+ * sp+X: argN |
+ * |
+ * When service runtime serves a system call, it first creates a structure which |
+ * utilizes these arguments. The structure is created by Decoder functions in |
+ * nacl_syscall_handlers.c. (nacl_syscall_handlers.c is an automatically |
+ * generated file and placed in |
+ * scons-out//gen/native_client/src/trusted/service_runtime). |
+ */ |
+ |
+ /* Place a0-a3 argument registers in the reserved 16-byte region in caller's |
+ stack frame (o32 ABI), and place return address on top of that. */ |
+ |
+ .cpload $t9 |
+ |
+ sw $a3, 12($sp) |
+ sw $a2, 8($sp) |
+ sw $a1, 4($sp) |
+ sw $a0, 0($sp) |
+ addiu $sp, $sp, -8 |
+ sw $ra, 4($sp) |
+ sw $t5, 0($sp) |
+ |
+ /* Load the __thread variable's offset into a3. */ |
+ lui $a3, %tprel_hi(gNaClThreadIdx) |
+ addiu $a3, $a3, %tprel_lo(gNaClThreadIdx) |
+ |
+ /* Fetch the thread-local variable holding the thread index. */ |
+ rdhwr $v1, $29 |
+ addu $a3, $v1, $a3 |
+ lw $a0, 0($a3) |
+ |
+ /* Load the nacl_user entry of this thread. |
+ * a1 = nacl_user[a0*4] */ |
+ lw $a1,%got(nacl_user)($28) |
+ sll $a0, $a0, 2 |
+ addu $a1, $a1, $a0 |
+ lw $a1, 0($a1) |
+ |
+ /* Store thread state to the nacl_user entry. */ |
+ sw $t6, 0($a1) |
Mark Seaborn
2012/09/08 02:43:14
Please don't hard code integer NaClThreadContext o
petarj
2012/09/11 16:58:13
Done.
|
+ sw $t7, 4($a1) |
+ sw $s0, 8($a1) |
+ sw $s1, 12($a1) |
+ sw $s2, 16($a1) |
+ sw $s3, 20($a1) |
+ sw $s4, 24($a1) |
+ sw $s5, 28($a1) |
+ sw $s6, 32($a1) |
+ sw $s7, 36($a1) |
+ sw $t8, 40($a1) |
+ sw $gp, 44($a1) |
+ sw $sp, 48($a1) |
+ sw $fp, 52($a1) |
+ |
+ /* Restore the thread index. */ |
+ srl $a0, $a0, 2 |
+ |
+ /* Reserve 16-byte for arguments (o32 ABI) */ |
+ addiu $sp, $sp, -16 |
+ lw $t9,%call16(NaClSyscallCSegHook)($gp) |
+ jr $t9 |
+ nop |
+ |
+ /* NOTREACHED */ |
+ |
+ /* |
+ * If the thread returns, which must not happen, it will be halted |
+ * by the following instruction |
+ */ |
+ |
+ jr $0 /*NACL_HALT*/ |
+ |