// Saved registers for kernel context switches. struct context { uint64 ra; uint64 sp; // callee-saved uint64 s0; uint64 s1; uint64 s2; uint64 s3; uint64 s4; uint64 s5; uint64 s6; uint64 s7; uint64 s8; uint64 s9; uint64 s10; uint64 s11; }; // Per-CPU state struct cpu { struct proc *proc; // The process running on this cpu or null struct context scheduler; // swtch() here to enter scheduler int noff; // Depth of push_off() nesting. int intena; // Were interrupts enabled before push_off()? }; extern struct cpu cpus[NCPU]; //PAGEBREAK: 17 // per-process data for the early trap handling code in trampoline.S. // sits in a page by itself just under the trampoline page in the // user page table. not specially mapped in the kernel page table. // the sscratch register points here. // trampoline.S saves user registers, then restores kernel_sp and // kernel_satp. // includes callee-saved registers like s0-s11 because the // return-to-user path via usertrapret() doesn't return through // the entire kernel call stack. struct trapframe { /* 0 */ uint64 kernel_satp; /* 8 */ uint64 kernel_sp; /* 16 */ uint64 kernel_trap; // usertrap() /* 24 */ uint64 epc; // saved user program counter /* 32 */ uint64 hartid; /* 40 */ uint64 ra; /* 48 */ uint64 sp; /* 56 */ uint64 gp; /* 64 */ uint64 tp; /* 72 */ uint64 t0; /* 80 */ uint64 t1; /* 88 */ uint64 t2; /* 96 */ uint64 s0; /* 104 */ uint64 s1; /* 112 */ uint64 a0; /* 120 */ uint64 a1; /* 128 */ uint64 a2; /* 136 */ uint64 a3; /* 144 */ uint64 a4; /* 152 */ uint64 a5; /* 160 */ uint64 a6; /* 168 */ uint64 a7; /* 176 */ uint64 s2; /* 184 */ uint64 s3; /* 192 */ uint64 s4; /* 200 */ uint64 s5; /* 208 */ uint64 s6; /* 216 */ uint64 s7; /* 224 */ uint64 s8; /* 232 */ uint64 s9; /* 240 */ uint64 s10; /* 248 */ uint64 s11; /* 256 */ uint64 t3; /* 264 */ uint64 t4; /* 272 */ uint64 t5; /* 280 */ uint64 t6; }; enum procstate { UNUSED, SLEEPING, RUNNABLE, RUNNING, ZOMBIE }; // Per-process state struct proc { struct spinlock lock; char *kstack; // Bottom of kernel stack for this process uint64 sz; // Size of process memory (bytes) pagetable_t pagetable; // Page table enum procstate state; // Process state int pid; // Process ID struct proc *parent; // Parent process struct trapframe *tf; // data page for trampoline.S struct context context; // swtch() here to run process void *chan; // If non-zero, sleeping on chan int killed; // If non-zero, have been killed struct file *ofile[NOFILE]; // Open files struct inode *cwd; // Current directory char name[16]; // Process name (debugging) }; // Process memory is laid out contiguously, low addresses first: // text // original data and bss // fixed-size stack // expandable heap