diff options
| -rw-r--r-- | defs.h | 2 | ||||
| -rw-r--r-- | proc.c | 8 | ||||
| -rw-r--r-- | proc.h | 26 | ||||
| -rw-r--r-- | swtch.S | 36 | 
4 files changed, 31 insertions, 41 deletions
| @@ -107,7 +107,7 @@ void            wakeup(void*);  void            yield(void);  // swtch.S -void            swtch(struct context*, struct context*); +void            swtch(struct context**, struct context**);  // spinlock.c  void            acquire(struct spinlock*); @@ -137,9 +137,9 @@ copyproc(struct proc *p)    }    // Set up new context to start executing at forkret (see below). -  memset(&np->context, 0, sizeof(np->context)); -  np->context.eip = (uint)forkret; -  np->context.esp = (uint)np->tf; +  np->context = (struct context *)np->tf - 1; +  memset(np->context, 0, sizeof(*np->context)); +  np->context->eip = (uint)forkret;    // Clear %eax so that fork system call returns 0 in child.    np->tf->eax = 0; @@ -477,7 +477,7 @@ procdump(void)        state = "???";      cprintf("%d %s %s", p->pid, state, p->name);      if(p->state == SLEEPING){ -      getcallerpcs((uint*)p->context.ebp+2, pc); +      getcallerpcs((uint*)p->context->ebp+2, pc);        for(j=0; j<10 && pc[j] != 0; j++)          cprintf(" %p", pc[j]);      } @@ -7,21 +7,17 @@  #define NSEGS     6  // Saved registers for kernel context switches. -// Don't need to save all the %fs etc. segment registers, +// Don't need to save all the segment registers (%cs, etc),  // because they are constant across kernel contexts. -// Save all the regular registers so we don't need to care -// which are caller save, but not the return register %eax. -// (Not saving %eax just simplifies the switching code.) +// Stack pointer is encoded in the address of context, +// which must be placed at the bottom of the stack.  // The layout of context must match code in swtch.S.  struct context { -  int eip; -  int esp; -  int ebx; -  int ecx; -  int edx; -  int esi; -  int edi; -  int ebp; +  uint edi; +  uint esi; +  uint ebx; +  uint ebp; +  uint eip;  };  enum proc_state { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE }; @@ -38,8 +34,8 @@ struct proc {    int killed;               // If non-zero, have been killed    struct file *ofile[NOFILE];  // Open files    struct inode *cwd;        // Current directory -  struct context context;   // Switch here to run process -  struct trapframe *tf;     // Trap frame for current interrupt +  struct context *context;  // Switch here to run process +  struct trapframe *tf;     // Trap frame for current syscall    char name[16];            // Process name (debugging)  }; @@ -53,7 +49,7 @@ struct proc {  struct cpu {    uchar apicid;               // Local APIC ID    struct proc *curproc;       // Process currently running. -  struct context context;     // Switch here to enter scheduler +  struct context *context;    // Switch here to enter scheduler    struct taskstate ts;        // Used by x86 to find stack for interrupt    struct segdesc gdt[NSEGS];  // x86 global descriptor table    volatile uint booted;        // Has the CPU started? @@ -1,32 +1,26 @@ -#   void swtch(struct context *old, struct context *new); +#   void swtch(struct context **old, struct context **new);  #    # Save current register context in old  # and then load register context from new.  .globl swtch  swtch: -  # Save old registers    movl 4(%esp), %eax +  movl 8(%esp), %edx -  popl 0(%eax)  # %eip -  movl %esp, 4(%eax) -  movl %ebx, 8(%eax) -  movl %ecx, 12(%eax) -  movl %edx, 16(%eax) -  movl %esi, 20(%eax) -  movl %edi, 24(%eax) -  movl %ebp, 28(%eax) +  # Save old callee-save registers +  pushl %ebp +  pushl %ebx +  pushl %esi +  pushl %edi -  # Load new registers -  movl 4(%esp), %eax  # not 8(%esp) - popped return address above - -  movl 28(%eax), %ebp -  movl 24(%eax), %edi -  movl 20(%eax), %esi -  movl 16(%eax), %edx -  movl 12(%eax), %ecx -  movl 8(%eax), %ebx -  movl 4(%eax), %esp -  pushl 0(%eax)  # %eip +  # Switch stacks +  movl %esp, (%eax) +  movl (%edx), %esp +  # Load new callee-save registers +  popl %edi +  popl %esi +  popl %ebx +  popl %ebp    ret | 
