#include "mem.h" #include "amd64.h" #ifndef __ASSEMBLER__ #define __ASSEMBLER__ #endif /* * starting the user program up. First time. */ .globl touser touser: cli swapgs movq $0, %r15 movq $0, %r14 movq $SSEL(SiUDS, SsRPL3), %rax movw %ax, %ds movw %ax, %es movw %ax, %fs movw %ax, %gs movq $(UTZERO+0x20), %rcx /* ip */ movq $If, %r11 /* flags */ movq %rdi, %rsp /* sp */ sysretq .globl syscallentry syscallentry: swapgs xchgq %gs:0, %r15 movq %r14, 24(%r15) /* save %r14 to m->tmp0 */ movq 16(%r15), %r14 /* m->proc (set up->) */ movq %r13, 32(%r15) /* save %r13 to m->tmp1 */ movq 16*8(%r14), %r13 /* m->proc->kstack (after the Label) */ xchgq %r13, %rsp movq 24(%r15), %r14 /* restore %r14 */ addq $KSTACK, %rsp /* build Ureg */ pushq $UDSEL /* old stack segment */ pushq %r13 /* old sp */ pushq %r11 /* old flags */ pushq $UESEL /* old code segment */ pushq %rcx /* old ip */ movq %r14, 24(%r15) /* restore %r14 from m->tmp0 */ movq %r13, 32(%r15) /* restore %r13 from m->tmp1 */ xchgq %gs:0, %r15 /* restore %r15 */ subq $(17*8), %rsp movq %rax, (0*8)(%rsp) // ureg.ax movq %rbx, (1*8)(%rsp) // ureg.bx movq %rcx, (2*8)(%rsp) // ureg.cx movq %rdx, (3*8)(%rsp) // ureg.dx movq %rsi, (4*8)(%rsp) // ... movq %rdi, (5*8)(%rsp) movq %rbp, (6*8)(%rsp) movq %r8, (7*8)(%rsp) movq %r9, (8*8)(%rsp) movq %r10, (9*8)(%rsp) movq %r11, (10*8)(%rsp) movq %r12, (11*8)(%rsp) movq %r13, (12*8)(%rsp) movq %r14, (13*8)(%rsp) movq %r15, (14*8)(%rsp) // (15*8)(%rsp) // ureg.type // (16*8)(%rsp) // ureg.error /* prepare m-> and up-> for the kernel */ movq %gs:0, %r15 movq 16(%r15), %r14 movq %rsp, %rsi /* Ureg* */ // system call number is in %rax, as per linux. movq %rax, %rdi xorq %rax, %rax pushq %rax popfq /* clear all flags. is there something else we should clear too? */ movq $0, %rbp /* stack traces end here */ call syscall .globl syscallreturn syscallreturn: // restore from ureg movq (0*8)(%rsp),%rax movq (1*8)(%rsp),%rbx movq (2*8)(%rsp),%rcx movq (3*8)(%rsp),%rdx movq (4*8)(%rsp),%rsi movq (5*8)(%rsp),%rdi movq (6*8)(%rsp),%rbp movq (7*8)(%rsp),%r8 movq (8*8)(%rsp),%r9 movq (9*8)(%rsp),%r10 movq (10*8)(%rsp),%r11 movq (11*8)(%rsp),%r12 movq (12*8)(%rsp),%r13 movq (13*8)(%rsp),%r14 movq (14*8)(%rsp),%r15 addq $(17*8), %rsp /* registers + arguments */ cli swapgs movq 0(%rsp), %rcx /* ip */ movq 16(%rsp), %r11 /* flags */ movq 24(%rsp), %rsp /* sp */ sysretq .globl sysrforkret sysrforkret: movq $0, 0(%rsp) // movq %r14, (13*8)(%rsp) /* preserve up-> */ // movq %r15, (14*8)(%rsp) /* preserve m-> */ jmp syscallreturn