cleaner swtch.S
This commit is contained in:
		
							parent
							
								
									228e500a0c
								
							
						
					
					
						commit
						c100d9ee2d
					
				
					 4 changed files with 31 additions and 41 deletions
				
			
		
							
								
								
									
										2
									
								
								defs.h
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								defs.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -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*);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										8
									
								
								proc.c
									
										
									
									
									
								
							
							
						
						
									
										8
									
								
								proc.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -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]);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										26
									
								
								proc.h
									
										
									
									
									
								
							
							
						
						
									
										26
									
								
								proc.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -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?
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										36
									
								
								swtch.S
									
										
									
									
									
								
							
							
						
						
									
										36
									
								
								swtch.S
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue