static void trap_dispatch(struct Trapframe *tf) { // Handle processor exceptions. // LAB 3: Your code here. // if (tf->tf_trapno == 14) // page_fault_handler(tf); cprintf("TRAP NO : %d\n", tf->tf_trapno); int r; switch (tf->tf_trapno) { case T_PGFLT : page_fault_handler(tf); break; case T_BRKPT : monitor(tf); break; case T_DEBUG : monitor(tf); break; case T_SYSCALL : r = syscall(tf->tf_regs.reg_eax, tf->tf_regs.reg_edx, tf->tf_regs.reg_ecx, tf->tf_regs.reg_ebx, tf->tf_regs.reg_edi, tf->tf_regs.reg_esi); tf->tf_regs.reg_eax = r; break; default : // Unexpected trap: The user process or the kernel has a bug. print_trapframe(tf); if (tf->tf_cs == GD_KT) panic("unhandled trap in kernel"); else { env_destroy(curenv); return; } } }
static int sys_env_swap(envid_t envid) { struct Env* e; if (envid2env(envid, &e, 1) < 0) { return -E_BAD_ENV; } if (e->env_status != ENV_NOT_RUNNABLE) { return -E_BAD_ENV; } struct Env temp = *curenv; curenv->env_tf = e->env_tf; curenv->env_pgdir = e->env_pgdir; lcr3(PADDR(curenv->env_pgdir)); // Need to do this to free old pgdir e->env_pgdir = temp.env_pgdir; e->env_tf = temp.env_tf; env_destroy(e); return 0; }
void main(void) { UCHAR cmd[0x8000]; BOOL exitflag; log_init(); hello(); log(greeting); log("DosLogWrite address: %x\n", DosLogWrite); exitflag=FALSE; // Ok. Here we just in endless loop. Except for EXIT command. // create the global env. array env_create(); while (!exitflag) { showpath(); read_cmd (cmd); exitflag = parse_cmd (cmd); } // destroy the global env. array env_destroy(); exit(0); }
env_h env_create( const env_h init_env ) { unsigned u ; env_s *ep ; unsigned max_vars ; if ( init_env == ENV_NULL ) max_vars = INITIAL_VARS ; else max_vars = init_env->n_vars + 5 ; ep = alloc_env( max_vars ) ; if ( ep == NULL ) { env_errno = ENV_ENOMEM ; return( ENV_NULL ) ; } if ( init_env == ENV_NULL ) return( ep ) ; for ( u = 0, ep->n_vars = 0 ; u < init_env->n_vars ; u++, ep->n_vars++ ) { ep->vars[ ep->n_vars ] = new_string( init_env->vars[ u ] ) ; if ( ep->vars[ ep->n_vars ] == NULL ) { env_destroy( ep ) ; env_errno = ENV_ENOMEM ; return( ENV_NULL ) ; } } return( ep ) ; }
static void trap_dispatch(struct Trapframe *tf) { // Handle processor exceptions. // LAB 3: Your code here. uint32_t fault_va; if(tf->tf_trapno >= 0 && tf->tf_trapno < 255) { switch(tf->tf_trapno) { case T_PGFLT://page fault page_fault_handler(tf); return; case T_BRKPT: monitor(tf); return; case T_SYSCALL: //fault_va = rcr2(); //cprintf("[%08x] user fault va %08x ip %08x\n",curenv->env_id, fault_va, tf->tf_eip); //cprintf("T_SYSCALL\n"); // print_trapframe(tf); tf->tf_regs.reg_eax = syscall(tf->tf_regs.reg_eax, tf->tf_regs.reg_edx, tf->tf_regs.reg_ecx,tf->tf_regs.reg_ebx, tf->tf_regs.reg_edi, tf->tf_regs.reg_esi); return; } } // Handle spurious interrupts // The hardware sometimes raises these because of noise on the // IRQ line or other reasons. We don't care. if (tf->tf_trapno == IRQ_OFFSET + IRQ_SPURIOUS) { cprintf("Spurious interrupt on irq 7\n"); print_trapframe(tf); return; } // Handle clock interrupts. Don't forget to acknowledge the // interrupt using lapic_eoi() before calling the scheduler! // LAB 4: Your code here. if (tf->tf_trapno == IRQ_OFFSET + IRQ_TIMER) { lapic_eoi(); sched_yield(); return; } // Handle keyboard and serial interrupts. // LAB 5: Your code here. // Unexpected trap: The user process or the kernel has a bug. print_trapframe(tf); if (tf->tf_cs == GD_KT) panic("unhandled trap in kernel"); else { env_destroy(curenv); return; } }
static int fill_entries(int ac, char **av, char **entries) { int i; int j; int flag; i = 0; j = 0; flag = 0; while (++i < ac) { if (!ft_strchr(av[i], '=')) { if (flag) break ; else continue ; } flag = 1; if (!(entries[j++] = ft_strdup(av[i]))) { env_destroy(&entries); return (-1); } } return (0); }
static void trap_dispatch(struct Trapframe *tf) { // Handle processor exceptions. // LAB 3: Your code here. // Handle clock and serial interrupts. // LAB 4: Your code here. switch(tf->tf_trapno){ case T_SYSCALL: tf->tf_regs.reg_eax = syscall(tf->tf_regs.reg_eax, tf->tf_regs.reg_edx, tf->tf_regs.reg_ecx, tf->tf_regs.reg_ebx, tf->tf_regs.reg_edi, tf->tf_regs.reg_esi); return ; case T_PGFLT: page_fault_handler(tf); return ; case T_BRKPT: monitor(tf); return ; case IRQ_OFFSET + IRQ_TIMER: sched_yield(); return ; } // Unexpected trap: The user process or the kernel has a bug. print_trapframe(tf); if (tf->tf_cs == GD_KT) panic("unhandled trap in kernel"); else { env_destroy(curenv); return; } }
static void trap_dispatch(struct Trapframe *tf) { // Handle processor exceptions. // LAB 3: Your code here. switch(tf->tf_trapno) { case T_PGFLT: page_fault_handler(tf); return; case T_BRKPT: monitor(tf); return; case T_SYSCALL: tf->tf_regs.reg_rax = syscall(tf->tf_regs.reg_rax,tf->tf_regs.reg_rdx,tf->tf_regs.reg_rcx,tf->tf_regs.reg_rbx, tf->tf_regs.reg_rdi, tf->tf_regs.reg_rsi); return; } // Unexpected trap: The user process or the kernel has a bug. print_trapframe(tf); if (tf->tf_cs == GD_KT) panic("unhandled trap in kernel"); else { env_destroy(curenv); return; } }
env_h env_make( char **env_strings ) { env_s *ep ; char **pp ; for ( pp = env_strings ; *pp ; pp++ ) ; ep = alloc_env( (unsigned) (pp-env_strings) ) ; if ( ep == NULL ) { env_errno = ENV_ENOMEM ; return( ENV_NULL ) ; } for ( pp = env_strings ; *pp ; pp++ ) { char *p = new_string( *pp ) ; if ( p == NULL ) { env_destroy( ep ) ; env_errno = ENV_ENOMEM ; return( ENV_NULL ) ; } ep->vars[ ep->n_vars++ ] = p ; } return( ep ) ; }
int nvm_set_parameter(const char *key, const char *value) { int env_valid = 0; int isEnv1Bad = -1; int isEnv2Bad = -1; int opt_sts = CMM_SUCCESS; env_t *env_ptr = NULL; isEnv1Bad = check_block("/dev/mtd2", 0); isEnv2Bad = check_block("/dev/mtd2", CFG_ENV_SIZE); if( -1 == isEnv1Bad ) { printf(" ERROR: check env block 1 failed\n"); return CMM_FAILED; } if( -1 == isEnv2Bad ) { printf(" ERROR: check env block 2 failed\n"); return CMM_FAILED; } /* either env1 or env2 is bad block, we do not permit set operation */ if( ( isEnv1Bad != 0 ) || ( isEnv2Bad != 0 ) ) { printf(" ERROR: env is broken\n"); return CMM_FAILED; } /* Get NVM */ env_ptr = env_init(&env_valid); if( NULL == env_ptr ) { printf(" ERROR: read env failed\n"); return CMM_FAILED; } /* modify ethaddr */ __do_env_set_parameter(env_ptr, key, value); /* update env crc */ __env_crc_update(env_ptr); /* save env to flash */ if( CMM_SUCCESS != __save_env(env_ptr, env_valid) ) { printf(" ERROR: save env failed\n\n"); opt_sts = CMM_FAILED; } else { opt_sts = CMM_SUCCESS; } /* free env_ptr malloced by function env_init() */ env_destroy(env_ptr); return opt_sts; }
status_e setup_environ( struct service_config *scp, struct service_config *def ) { struct environment *ep = SC_ENV( scp ) ; if ( ! SC_SPECIFIED( scp, A_PASSENV ) ) { if ( ! SC_SPECIFIED( def, A_PASSENV ) ) { if ( ! SC_SPECIFIED( scp, A_ENV ) ) { ep->env_type = STD_ENV ; ep->env_handle = std_env ; return( OK ) ; } else return( make_env_with_strings( ep, std_env, SC_ENV_VAR_DEFS(scp) ) ) ; } else /* SC_SPECIFIED( def, A_PASSENV ) */ { struct environment *dep = SC_ENV( def ) ; if ( dep->env_type == NO_ENV && make_env_from_vars( dep, std_env, SC_PASS_ENV_VARS(def) ) == FAILED ) return( FAILED ) ; if ( ! SC_SPECIFIED( scp, A_ENV ) ) { ep->env_type = DEF_ENV ; ep->env_handle = dep->env_handle ; return( OK ) ; } else return( make_env_with_strings( ep, dep->env_handle, SC_ENV_VAR_DEFS(scp) ) ) ; } } else /* SC_SPECIFIED( scp, A_PASSENV ) */ { if ( make_env_from_vars( ep, std_env, SC_PASS_ENV_VARS(scp) ) == FAILED ) return( FAILED ) ; if ( ! SC_SPECIFIED( scp, A_ENV ) ) return( OK ) ; else { if ( update_env_with_strings( ep->env_handle, SC_ENV_VAR_DEFS(scp) ) == FAILED ) { env_destroy( ep->env_handle ) ; return( FAILED ) ; } return( OK ) ; } } }
// // Checks that environment 'env' is allowed to access the range // of memory [va, va+len) with permissions 'perm | PTE_U | PTE_P'. // If it can, then the function simply returns. // If it cannot, 'env' is destroyed and, if env is the current // environment, this function will not return. // void user_mem_assert(struct Env *env, const void *va, size_t len, int perm) { if (user_mem_check(env, va, len, perm | PTE_U) < 0) { cprintf("[%08x] user_mem_check assertion failure for " "va %08x\n", env->env_id, user_mem_check_addr); env_destroy(env); // may not return } }
void page_fault_handler(struct Trapframe *tf) { uint32_t fault_va; // Read processor's CR2 register to find the faulting address fault_va = rcr2(); cprintf("fault_va: %x\n", fault_va); // Handle kernel-mode page faults. // LAB 3: Your code here. if ((tf->tf_cs&3) == 0) { panic("Kernel page fault!"); } // We've already handled kernel-mode exceptions, so if we get here, // the page fault happened in user mode. // Call the environment's page fault upcall, if one exists. Set up a // page fault stack frame on the user exception stack (below // UXSTACKTOP), then branch to curenv->env_pgfault_upcall. if (curenv->env_pgfault_upcall) { // // The page fault upcall might cause another page fault, in which case // we branch to the page fault upcall recursively, pushing another // page fault stack frame on top of the user exception stack. // // The trap handler needs one word of scratch space at the top of the // trap-time stack in order to return. In the non-recursive case, we // don't have to worry about this because the top of the regular user // stack is free. In the recursive case, this means we have to leave // an extra word between the current top of the exception stack and // the new stack frame because the exception stack _is_ the trap-time // stack. // // If there's no page fault upcall, the environment didn't allocate a // page for its exception stack or can't write to it, or the exception // stack overflows, then destroy the environment that caused the fault. // Note that the grade script assumes you will first check for the page // fault upcall and print the "user fault va" message below if there is // none. The remaining three checks can be combined into a single test. // // Hints: // user_mem_assert() and env_run() are useful here. // To change what the user environment runs, modify 'curenv->env_tf' // (the 'tf' variable points at 'curenv->env_tf'). // LAB 4: Your code here. } // Destroy the environment that caused the fault. cprintf("[%08x] user fault va %08x ip %08x\n", curenv->env_id, fault_va, tf->tf_eip); print_trapframe(tf); env_destroy(curenv); }
void nvm_dump(void) { int env_valid = 0; int isEnv1Bad = -1; int isEnv2Bad = -1; struct mtd_info_user info; env_t *env_ptr = NULL; if( CMM_SUCCESS != get_mtd_info("/dev/mtd2", &info) ) { printf(" ERROR: can not get mtd info\n"); return; } isEnv1Bad = check_block("/dev/mtd2", 0); isEnv2Bad = check_block("/dev/mtd2", CFG_ENV_SIZE); if( -1 == isEnv1Bad ) { printf(" ERROR: check env block 1 failed\n"); return; } if( -1 == isEnv2Bad ) { printf(" ERROR: check env block 2 failed\n"); return; } if( ( isEnv1Bad != 0 ) || ( isEnv2Bad != 0 ) ) { printf(" ERROR: env is broken\n"); return; } env_ptr = env_init(&env_valid); if( NULL == env_ptr ) { printf(" ERROR: read env failed\n"); return; } printf("nvm device name: mtd2\n"); printf("device type: %d\n", info.type); printf("nvm total size: %d KiB\n", info.size/1024); printf("block size: %d KiB\n", info.erasesize/1024); printf("page size: %d KiB\n", info.writesize/1024); printf("oob size: %d bytes\n", info.oobsize); printf("bad blocks: 0\n"); printf("env config size: %d KiB\n", CFG_ENV_SIZE/1024); printf("env valid: %d\n", env_valid); __debug_printf_env(env_ptr); env_destroy(env_ptr); }
static void trap_dispatch(struct Trapframe *tf) { // Handle processor exceptions. // LAB 3: Your code here. // Handle spurious interrupts // The hardware sometimes raises these because of noise on the // IRQ line or other reasons. We don't care. if (tf->tf_trapno == IRQ_OFFSET + IRQ_SPURIOUS) { cprintf("Spurious interrupt on irq 7\n"); print_trapframe(tf); return; } // Handle clock interrupts. Don't forget to acknowledge the // interrupt using lapic_eoi() before calling the scheduler! // LAB 4: Your code here. if (tf ->tf_trapno == IRQ_OFFSET + IRQ_TIMER) { lapic_eoi(); sched_yield(); return; } // Unexpected trap: The user process or the kernel has a bug. // if (tf->tf_trapno == 14) // page_fault_handler(tf); // cprintf("TRAP NO : %d\n", tf->tf_trapno); int r; switch (tf->tf_trapno) { case T_PGFLT : page_fault_handler(tf); break; case T_BRKPT : monitor(tf); break; case T_DEBUG : monitor(tf); break; case T_SYSCALL : r = syscall(tf->tf_regs.reg_eax, tf->tf_regs.reg_edx, tf->tf_regs.reg_ecx, tf->tf_regs.reg_ebx, tf->tf_regs.reg_edi, tf->tf_regs.reg_esi); tf->tf_regs.reg_eax = r; break; default : // Unexpected trap: The user process or the kernel has a bug. print_trapframe(tf); if (tf->tf_cs == GD_KT) panic("unhandled trap in kernel"); else { env_destroy(curenv); return; } } }
// Destroy a given environment (possibly the currently running environment). // // Returns 0 on success, < 0 on error. Errors are: // -E_BAD_ENV if environment envid doesn't currently exist, // or the caller doesn't have permission to change envid. static int sys_env_destroy(envid_t envid) { int r; struct Env *e; if ((r = envid2env(envid, &e, 1)) < 0) return r; env_destroy(e); return 0; }
BDNProgram *bd_alpha_convert(BDNProgram *prog) { BDNProgram *nprog = malloc(sizeof(BDNProgram)); bd_nprogram_init(nprog); Vector *vec; BDNExprDef *def; int i; Env *env = env_new(); // set primitive labels to env PrimSig *sig; for(i = 0; i < primsigs->length; i++){ sig = vector_get(primsigs, i); env_set(env, sig->name, sig->lbl); } // set toplevel names to env vec = prog->defs; for(i = 0; i < vec->length; i++){ def = vector_get(vec, i); env_set(env, def->ident->name, bd_generate_toplevel_lbl(def->ident->name)); } // convert defs vec = prog->defs; for(i = 0; i < vec->length; i++){ def = vector_get(vec, i); vector_add(nprog->defs, bd_nexpr_def( bd_expr_ident(find_alt_name(env, def->ident->name), bd_type_clone(def->ident->type)), bd_alpha(env, def->body) )); } // convert maindef def = prog->maindef; nprog->maindef = bd_nexpr_def( bd_expr_ident(bd_generate_toplevel_lbl(def->ident->name), bd_type_clone(def->ident->type)), bd_alpha(env, def->body) ); // destroy vec = prog->defs; for(i = 0; i < vec->length; i++){ def = vector_get(vec, i); free(env_get(env, def->ident->name)); } env_destroy(env); bd_nprogram_destroy(prog); return nprog; }
// Destroy a given environment (possibly the currently running environment). // // Returns 0 on success, < 0 on error. Errors are: // -E_BAD_ENV if environment envid doesn't currently exist, // or the caller doesn't have permission to change envid. static int sys_env_destroy(envid_t envid, int retcode) { int r; struct Env *e; if ((r = envid2env(envid, &e, 1)) < 0) return r; e->env_retcode = retcode; env_destroy(e); return 0; }
void trap(struct Trapframe *tf) { int ret; // Handle processor exceptions // Your code here. switch(tf->tf_trapno) { case T_BRKPT: while(1) monitor(NULL); break; case T_PGFLT: page_fault_handler(tf); tf->tf_eflags |= FL_IF; //env_pop_tf(tf); memcpy(&curenv->env_tf, tf, sizeof(*tf)); env_run(curenv); return; case T_SYSCALL: ret = syscall(tf->tf_eax, tf->tf_edx, tf->tf_ecx, tf->tf_ebx, tf->tf_edi, tf->tf_esi); tf->tf_eax = ret; tf->tf_eflags |= FL_IF; // env_pop_tf(tf); memcpy(&curenv->env_tf, tf, sizeof(*tf)); env_run(curenv); case IRQ_OFFSET: sched_yield(); break; case IRQ_KBD: kbd_intr(); memcpy(&curenv->env_tf, tf, sizeof(*tf)); env_run(curenv); break; default: break; } // the user process or the kernel has a bug. print_trapframe(tf); if (tf->tf_cs == GD_KT) panic("unhandled trap in kernel"); else { env_destroy(curenv); return; } }
// Destroy a given environment (possibly the currently running environment). // // Returns 0 on success, < 0 on error. Errors are: // -E_BAD_ENV if environment envid doesn't currently exist, // or the caller doesn't have permission to change envid. static int sys_env_destroy(envid_t envid) { int r; struct Env *e; if ((r = envid2env(envid, &e, 1)) < 0) return r; if (e == curenv) cprintf("[%08x] exiting gracefully\n", curenv->env_id); else cprintf("[%08x] destroying %08x\n", curenv->env_id, e->env_id); env_destroy(e); return 0; }
static void trap_dispatch(struct Trapframe *tf) { // Handle processor exceptions. // LAB 3: Your code here. // Unexpected trap: The user process or the kernel has a bug. print_trapframe(tf); if (tf->tf_cs == GD_KT) panic("unhandled trap in kernel"); else { env_destroy(curenv); return; } }
void page_fault_handler(struct Trapframe *tf) { u_int fault_va; // Read processor's CR2 register to find the faulting address fault_va = rcr2(); // User-mode exception - destroy the environment. printf("[%08x] user fault va %08x ip %08x\n", curenv->env_id, fault_va, tf->tf_eip); print_trapframe(tf); env_destroy(curenv); }
// destroy the current environment void sys_env_destroy(int sysno,u_int envid) { /* printf("[%08x] exiting gracefully\n", curenv->env_id); env_destroy(curenv); */ int r; struct Env *e; if ((r=envid2env(envid, &e, 1)) < 0) return r; printf("[%08x] destroying %08x\n", curenv->env_id, e->env_id); env_destroy(e); return 0; }
static void trap_dispatch(struct Trapframe *tf) { // Handle processor exceptions. // LAB 3: Your code here. uint32_t ret; if ( tf->tf_trapno == T_PGFLT ) { page_fault_handler(tf); return; } if ( tf->tf_trapno == T_BRKPT ) { monitor(tf); return; } if ( tf->tf_trapno == T_SYSCALL ) { //cprintf("==== i am here\n"); ret = syscall( tf->tf_regs.reg_eax, tf->tf_regs.reg_edx, tf->tf_regs.reg_ecx, tf->tf_regs.reg_ebx, tf->tf_regs.reg_edi, tf->tf_regs.reg_esi); if ( ret < 0 ) { panic("trap_dispatch: The System Call number is invalid"); } tf->tf_regs.reg_eax = ret; //cprintf("bobo -------------:%x\n", tf->tf_regs.reg_eax); return; } // Handle spurious interrupts // The hardware sometimes raises these because of noise on the // IRQ line or other reasons. We don't care. if (tf->tf_trapno == IRQ_OFFSET + IRQ_SPURIOUS) { cprintf("Spurious interrupt on irq 7\n"); print_trapframe(tf); return; } // Handle clock interrupts. Don't forget to acknowledge the // interrupt using lapic_eoi() before calling the scheduler! // LAB 4: Your code here. // Unexpected trap: The user process or the kernel has a bug. print_trapframe(tf); if (tf->tf_cs == GD_KT) panic("unhandled trap in kernel"); else { env_destroy(curenv); return; } }
/** Main test */ int main( int argc, char **argv ) { setlocale( LC_ALL, "" ); srand( time( 0 ) ); program_name=L"(ignore)"; say( L"Testing low-level functionality"); say( L"Lines beginning with '(ignore):' are not errors, they are warning messages\ngenerated by the fish parser library when given broken input, and can be\nignored. All actual errors begin with 'Error:'." ); proc_init(); halloc_util_init(); event_init(); parser_init(); function_init(); builtin_init(); reader_init(); env_init(); test_util(); test_escape(); test_convert(); test_tok(); test_parser(); test_expand(); test_path(); say( L"Encountered %d errors in low-level tests", err_count ); /* Skip performance tests for now, since they seem to hang when running from inside make (?) */ // say( L"Testing performance" ); // perf_complete(); env_destroy(); reader_destroy(); parser_destroy(); function_destroy(); builtin_destroy(); wutil_destroy(); event_destroy(); proc_destroy(); halloc_util_destroy(); }
int nvm_get_parameter(const char *key, char *value) { int env_valid = 0; int isEnv1Bad = -1; int isEnv2Bad = -1; env_t *env_ptr = NULL; isEnv1Bad = check_block("/dev/mtd2", 0); isEnv2Bad = check_block("/dev/mtd2", CFG_ENV_SIZE); if( -1 == isEnv1Bad ) { printf(" ERROR: check env block 1 failed\n"); return CMM_FAILED; } if( -1 == isEnv2Bad ) { printf(" ERROR: check env block 2 failed\n"); return CMM_FAILED; } /* either env1 or env2 is bad block, we do not permit set operation */ if( ( isEnv1Bad != 0 ) || ( isEnv2Bad != 0 ) ) { printf(" ERROR: env is broken\n"); return CMM_FAILED; } /* Get NVM */ env_ptr = env_init(&env_valid); if( NULL == env_ptr ) { printf(" ERROR: read env failed\n"); return CMM_FAILED; } /* get parameter */ __do_env_get_parameter(env_ptr, key, value); /* free env_ptr malloced by function env_init() */ env_destroy(env_ptr); return CMM_SUCCESS; }
void trap(struct Trapframe *tf) { // print_trapframe(tf); // Handle processor exceptions // Your code here. if(tf->tf_trapno == 0xE) page_fault_handler(tf); else if(tf->tf_trapno == T_SYSCALL) { syscall(tf->tf_eax, tf->tf_edx, tf->tf_ecx, tf->tf_ebx, tf->tf_esi, tf->tf_edi); } // Handle external interrupts if (tf->tf_trapno == IRQ_OFFSET+0) { // irq 0 -- clock interrupt sched_yield(); } if (tf->tf_trapno == IRQ_OFFSET+4) { serial_intr(); return; } if (IRQ_OFFSET <= tf->tf_trapno && tf->tf_trapno < IRQ_OFFSET+MAX_IRQS) { // just ingore spurious interrupts printf("spurious interrupt on irq %d\n", tf->tf_trapno - IRQ_OFFSET); print_trapframe(tf); return; } // the user process or the kernel has a bug. print_trapframe(tf); if (tf->tf_cs == GD_KT) panic("unhandled trap in kernel"); else { env_destroy(curenv); return; } }
void page_fault_handler(struct Trapframe *tf) { uint32_t fault_va; // Read processor's CR2 register to find the faulting address fault_va = rcr2(); // Handle kernel-mode page faults. // LAB 3: Your code here. // We've already handled kernel-mode exceptions, so if we get here, // the page fault happened in user mode. // Destroy the environment that caused the fault. cprintf("[%08x] user fault va %08x ip %08x\n", curenv->env_id, fault_va, tf->tf_eip); print_trapframe(tf); env_destroy(curenv); }
// Print a string to the system console. // The string is exactly 'len' characters long. // Destroys the environment on memory errors. static void sys_cputs(const char *s, size_t len) { // Check that the user has permission to read memory [s, s+len). // Destroy the environment if not. // LAB 3: Your code here. user_mem_assert(curenv, (void *)s, len, PTE_U | PTE_P | PTE_W); pte_t * ptx; uint32_t st = ROUNDDOWN((uint32_t) s,PGSIZE); while(st < (uint32_t)s + len ){ ptx=pgdir_walk(curenv->env_pgdir,(void *)st, 0); if(!ptx || !(*ptx & PTE_P) || !(*ptx & PTE_U) ) env_destroy(curenv); st+=PGSIZE; } // Print the string supplied by the user. cprintf("%.*s", len, s); }
static void trap_dispatch(struct Trapframe *tf) { int32_t ret_code; // Handle processor exceptions. // LAB 3: Your code here. switch(tf->tf_trapno) { case (T_PGFLT): page_fault_handler(tf); break; case (T_BRKPT): print_trapframe(tf); monitor(tf); break; case (T_DEBUG): monitor(tf); break; case (T_SYSCALL): // print_trapframe(tf); ret_code = syscall( tf->tf_regs.reg_eax, tf->tf_regs.reg_edx, tf->tf_regs.reg_ecx, tf->tf_regs.reg_ebx, tf->tf_regs.reg_edi, tf->tf_regs.reg_esi); tf->tf_regs.reg_eax = ret_code; break; default: // Unexpected trap: The user process or the kernel has a bug. print_trapframe(tf); if (tf->tf_cs == GD_KT) panic("unhandled trap in kernel"); else { env_destroy(curenv); return; } } }