void StartProcISR(int new_pid, int func_addr) { MyBzero( (char*) &pcb[new_pid], sizeof (pcb_t)); //clear process msg queue MyBzero( (char*) &msg_q[new_pid], sizeof (msg_q_t)); pcb[new_pid].state= READY; if(new_pid > 0 ) { EnQ(new_pid, &ready_q); } MyBzero( (char*) &proc_stack[new_pid], PROC_STACK_SIZE); pcb[new_pid].TF_ptr =(TF_t*) &proc_stack[new_pid][PROC_STACK_SIZE]; pcb[new_pid].TF_ptr--; pcb[new_pid].TF_ptr->eflags = EF_DEFAULT_VALUE|EF_INTR; // set INTR flag pcb[new_pid].TF_ptr->cs = get_cs(); // standard fair pcb[new_pid].TF_ptr->ds = get_ds(); // standard fair pcb[new_pid].TF_ptr->es = get_es(); // standard fair pcb[new_pid].TF_ptr->fs = get_fs(); // standard fair pcb[new_pid].TF_ptr->gs = get_gs(); // standard fair pcb[new_pid].TF_ptr->eip = (unsigned int) func_addr; }
void StartProcISR(int new_pid, int func_addr) { MyBzero((char *) &pcb[new_pid], sizeof(pcb_t)); //clear the PCB of the new pid //phase 5 MyBzero((char *) &msg_q[new_pid], sizeof(msg_q_t)); pcb[new_pid].state = READY; //set its state to READY if(new_pid != 0) //if new pid is not 0 (IdleProc), { EnQ(new_pid, &ready_q); //then, enqueue this new pid into the ready queue } //build initial trapframe in proc stack MyBzero((char *)&proc_stack[new_pid], PROC_STACK_SIZE); //call MyBzero() to clear the stack 1st pcb[new_pid].TF_ptr = (TF_t *) &proc_stack[new_pid][PROC_STACK_SIZE - sizeof(TF_t)]; //set TF_ptr of PCB to close to end (top) of stack pcb[new_pid].TF_ptr->eflags = EF_DEFAULT_VALUE|EF_INTR; //set INTR flag pcb[new_pid].TF_ptr->cs = get_cs(); //standard fair pcb[new_pid].TF_ptr->ds = get_ds(); //standard fair pcb[new_pid].TF_ptr->es = get_es(); //standard fair pcb[new_pid].TF_ptr->fs = get_fs(); //standard fair pcb[new_pid].TF_ptr->gs = get_gs(); //standard fair pcb[new_pid].TF_ptr->eip = func_addr; }
void StartProcISR(int new_pid) { //clear the PCB of the new pid MyBzero((char *) &pcb[new_pid], sizeof(pcb_t)); //set its state to READY pcb[new_pid].state = READY; //if new pid is not 0 (IdleProc), //then, enqueue this new pid into the ready queue*/ if(new_pid != 0){ EnQ(new_pid, &ready_q); } //Clears the stack MyBzero((char *) &proc_stack[new_pid], PROC_STACK_SIZE); //Set TF_ptr of PCB close to end (top) of stack, then fill out pcb[new_pid].TF_ptr = (TF_t *) &proc_stack[new_pid][PROC_STACK_SIZE - sizeof(TF_t)]; pcb[new_pid].TF_ptr->eflags = EF_DEFAULT_VALUE|EF_INTR; // set INTR flag pcb[new_pid].TF_ptr->cs = get_cs(); // standard fair pcb[new_pid].TF_ptr->ds = get_ds(); // standard fair pcb[new_pid].TF_ptr->es = get_es(); // standard fair pcb[new_pid].TF_ptr->fs = get_fs(); // standard fair pcb[new_pid].TF_ptr->gs = get_gs(); // standard fair if(new_pid == 0){ pcb[new_pid].TF_ptr->eip = (unsigned int) IdleProc; // if pid is 0, points to IdleProc }else{ pcb[new_pid].TF_ptr->eip = (unsigned int) UserProc; // or UserProc } }
void SpawnISR(int pid, func_ptr_t addr) { MyBZero(user_stacks[pid], USER_STACK_SIZE); MyBZero((char *) &mboxes[pid], sizeof(mbox_t)); // 1st. point to just above of user stack, then drop by 64 bytes (tf_t) pcbs[pid].tf_p = (tf_t *)&user_stacks[pid][USER_STACK_SIZE]; pcbs[pid].tf_p--; // pointer arithmetic, now points to trapframe // fill in CPU's register context pcbs[pid].tf_p->eflags = EF_DEFAULT_VALUE|EF_INTR; //pcbs[pid].tf_p->eip = (unsigned int)SimpleProc; // new process code pcbs[pid].tf_p->eip = (unsigned int)addr; pcbs[pid].tf_p->cs = get_cs(); pcbs[pid].tf_p->ds = get_ds(); pcbs[pid].tf_p->es = get_es(); pcbs[pid].tf_p->fs = get_fs(); pcbs[pid].tf_p->gs = get_gs(); pcbs[pid].tick_count = pcbs[pid].total_tick_count = 0; pcbs[pid].state = READY; if(pid != 0) EnQ(pid, &ready_q); // IdleProc (PID 0) is not queued }
/* * Blackbox testing of the per-CPU accessors. */ void percpu_run_tests(void) { int id; uintptr_t self, gs; id = percpu_get(apic_id); self = percpu_get(self); gs = get_gs(); printk("_PerCPU#%d: area address: self = 0x%lx, %%gs = 0x%lx\n", id, self, gs); if (self != gs) panic("_PerCPU#%d: self reference '0x%lx' != %%gs", id, self); *percpu_addr(x64) = 0x6464646464646464; percpu_set(x32, 0x32323232); percpu_set(x16, 0x1616); percpu_set(x8, 0x8); printk("_PerCPU#%d: x64 address = 0x%lx, val = 0x%lx\n", id, percpu_addr(x64), percpu_get(x64)); printk("_PerCPU#%d: x32 address = 0x%lx, val = 0x%x\n", id, percpu_addr(x32), percpu_get(x32)); printk("_PerCPU#%d: x16 address = 0x%lx, val = 0x%x\n", id, percpu_addr(x16), percpu_get(x16)); printk("_PerCPU#%d: x8 address = 0x%lx, val = 0x%x\n", id, percpu_addr(x8 ), percpu_get(x8 )); }
void* child(void * arg) { printf("[child] started\n"); printf("[child] tls fs: %p\n", (void*) get_fs()); printf("[child] tls gs: %p\n", (void*) get_gs()); print_id("child", 0, &thread_i); usleep(500000); return NULL; }
/** @brief Print out the registers * * This function is called to dump the registers when a thread is killed * by the kernel because of a fault or exception. * * @param type: Has error code or not * @param cause: The cause of this exception or fault * @param msg: The error message * * @return void */ void dump_regs(int type, int cause, char* msg) { unsigned int *ureg = (unsigned int*)cur_thread->esp0; unsigned int ss = *(--ureg); unsigned int esp = *(--ureg); unsigned int eflags = *(--ureg); unsigned int cs = *(--ureg); unsigned int eip = *(--ureg); if(type == NO_ERROR_CODE) --ureg; unsigned int eax = *(--ureg); unsigned int ecx = *(--ureg); unsigned int edx = *(--ureg); unsigned int ebx = *(--ureg); unsigned int ebp = *(--ureg); unsigned int esi = *(--ureg); unsigned int edi = *(--ureg); unsigned int gs = get_gs(); unsigned int fs = get_fs(); unsigned int es = get_es(); unsigned int ds = get_ds(); unsigned int cr2 = get_cr2(); char buf[512]; int len = 0; len += sprintf(buf+len, "%s\n", msg); len += sprintf(buf+len, "cause: %d ", cause); len += sprintf(buf+len, "cr2: 0x%8x ", cr2); len += sprintf(buf+len, "ds: 0x%8x \n", ds); len += sprintf(buf+len, "es: 0x%8x ", es); len += sprintf(buf+len, "fs: 0x%8x ", fs); len += sprintf(buf+len, "gs: 0x%8x \n", gs); len += sprintf(buf+len, "eip: 0x%8x ", eip); len += sprintf(buf+len, "cs: 0x%8x ", cs); len += sprintf(buf+len, "eflags: 0x%8x \n", eflags); len += sprintf(buf+len, "esp: 0x%8x ", esp); len += sprintf(buf+len, "ss: 0x%8x ", ss); len += sprintf(buf+len, "eax: 0x%8x \n", eax); len += sprintf(buf+len, "ecx: 0x%8x ", ecx); len += sprintf(buf+len, "edx: 0x%8x ", edx); len += sprintf(buf+len, "ebx: 0x%8x \n", ebx); len += sprintf(buf+len, "ebp: 0x%8x ", ebp); len += sprintf(buf+len, "esi: 0x%8x ", esi); len += sprintf(buf+len, "edi: 0x%8x \n\n", edi); printf("%s",buf); return; }
int main(void) { int tid, status; printf("[main_] started\n"); printf("[main_] tls fs: %p\n", (void*) get_fs()); printf("[main_] tls gs: %p\n", (void*) get_gs()); tid = new_thread(&child); printf("[main_] child launched: %d\n", tid); print_id("main_", 1, &thread_i); usleep(500000); return EXIT_SUCCESS; }
void ForkISR(int pid, int* addr, int size, int value) { // Only thing new for ForkISR int i; int * p; for(i=0;i<NUM_PAGE;i++) { if(pages[i].owner == -1) break; } // The rest was a copy from spwnisr. pages[i].owner = pid; MyBzero((char *)pages[i].addr, USER_STACK_SIZE); MyBzero((void *)user_stacks[pid], USER_STACK_SIZE); MyBzero(&mboxes[pid], sizeof(mbox_t)); p = (int *) (pages[i].addr + USER_STACK_SIZE); p--; *p = value; pcbs[pid].tf_p = (tf_t*) p; pcbs[pid].tf_p--; // points to trap frame MyMemCpy((char *)(pages[i].addr), (char *)(addr), size); pcbs[pid].tf_p->eflags = EF_DEFAULT_VALUE|EF_INTR; pcbs[pid].tf_p->eip = pages[i].addr; pcbs[pid].tf_p->cs = get_cs(); pcbs[pid].tf_p->ds = get_ds(); pcbs[pid].tf_p->es = get_es(); pcbs[pid].tf_p->fs = get_fs(); pcbs[pid].tf_p->gs = get_gs(); pcbs[pid].tick_count = pcbs[pid].total_tick_count = 0; pcbs[pid].state = READY; pcbs[pid].ppid = cur_pid; EnQ(pid, &ready_q); }