Skip to content
Snippets Groups Projects
Commit c100d9ee authored by kolya's avatar kolya
Browse files

cleaner swtch.S

parent 228e500a
No related branches found
No related tags found
No related merge requests found
......@@ -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?
......
# 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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment