/* Simulate how the CPU works. */ void cpu_exec(volatile uint32_t n) { if(nemu_state == END) { printf("Program execution has ended. To restart the program, exit NEMU and run again.\n"); return; } nemu_state = RUNNING; #ifdef DEBUG volatile uint32_t n_temp = n; #endif setjmp(jbuf); for(; n > 0; n --) { #ifdef DEBUG swaddr_t eip_temp = cpu.eip; if((n & 0xffff) == 0) { /* Output some dots while executing the program. */ fputc('.', stderr); } #endif /* Execute one instruction, including instruction fetch, * instruction decode, and the actual execution. */ int instr_len = exec(cpu.eip); // if (cpu.eip>=0xc0100740 && cpu.eip <=0xc0100744) printf("%08x %d\n", cpu.eip, instr_len); cpu.eip += instr_len; // if (cpu.eip>=0xc0100740 && cpu.eip <=0xc0100744) printf("%08x %d\n", cpu.eip, instr_len); #ifdef DEBUG print_bin_instr(eip_temp, instr_len); strcat(asm_buf, assembly); Log_write("%s\n", asm_buf); if(n_temp < MAX_INSTR_TO_PRINT) { printf("%s\n", asm_buf); } #endif /* TODO: check watchpoints here. */ if (check()) { nemu_state=STOP; } if(nemu_state != RUNNING) { return; } if(cpu.INTR & eflags.IF) { uint32_t intr_no = i8259_query_intr(); i8259_ack_intr(); int len; len = get_len(); cpu.eip--; raise_intr(intr_no, len); } } if(nemu_state == RUNNING) { nemu_state = STOP; } }
int int_polling() { if(cpu.INTR & FLAG_VAL(IF)) { uint32_t intr_no = i8259_query_intr(); i8259_ack_intr(); raise_intr(intr_no); return 0; } return 1; }
/* Simulate how the CPU works. */ void cpu_exec(volatile uint32_t n) { if(nemu_state == END) { printf("Program execution has ended. To restart the program, exit NEMU and run again.\n"); return; } nemu_state = RUNNING; #ifdef DEBUG volatile uint32_t n_temp = n; #endif setjmp(jbuf); for(; n > 0; n --) { #ifdef DEBUG swaddr_t eip_temp = cpu.eip; if((n & 0xffff) == 0) { /* Output some dots while executing the program. */ fputc('.', stderr); } #endif /* Execute one instruction, including instruction fetch, * instruction decode, and the actual execution. */ int instr_len = exec(cpu.eip); cpu.eip += instr_len; #ifdef DEBUG print_bin_instr(eip_temp, instr_len); strcat(asm_buf, assembly); Log_write("%s\n", asm_buf); if(n_temp < MAX_INSTR_TO_PRINT) { printf("%s\n", asm_buf); } #endif /* TODO: check watchpoints here. */ WP *p; uint32_t index; bool success=true; p=gethead(); int flag=0; while(p!=NULL) { index=expr(p->expr,&success); if(success==false) printf("Meet a wrong expression!"); if(p->ans!=index) { flag=1; printf("watchpoint %d: %s\n",p->NO+1,p->expr); printf("Old value = %d\n",p->ans); printf("New value = %d\n",index); p->ans=index; } p=p->next; } if(flag==1) nemu_state=STOP; if(nemu_state != RUNNING) { return; } if(cpu.INTR & cpu.EFLAGS.IF) { uint32_t intr_no = i8259_query_intr(); i8259_ack_intr(); raise_intr(intr_no); } } if(nemu_state == RUNNING) { nemu_state = STOP; } }
void cpu_exec(volatile uint32_t n) { if(nemu_state == END) { printf("Program execution has ended. To restart the program, exit NEMU and run again.\n"); return; } nemu_state = RUNNING; #ifdef DEBUG volatile uint32_t n_temp = n; #endif setjmp(jbuf); for(; n > 0; n --) { #ifdef DEBUG swaddr_t eip_temp = cpu.eip; if((n & 0xffff) == 0) { /* Output some dots while executing the program. */ fputc('.', stderr); } #endif /* Execute one instruction, including instruction fetch, * instruction decode, and the actual execution. */ int instr_len = exec(cpu.eip); //printf("instr_len is %x in cpu-exec.c\n",instr_len); cpu.eip += instr_len; si_count++; #ifdef DEBUG #endif print_bin_instr(eip_temp, instr_len); strcat(asm_buf, assembly); Log_write("%s\n", asm_buf); if(n_temp < MAX_INSTR_TO_PRINT) { printf("%s\n", asm_buf); } /* TODO: check watchpoints here. */ if(check_watchpoints()){ n=1; nemu_state = STOP; } if(nemu_state != RUNNING) { printf("Cache cost = %llu, L1 miss rate = %f, L2 miss rate = %f\n",(unsigned long long)(L2_get_cache_cost()+L1_get_cache_cost()), (double)L1_cache_miss/(double)L1_cache_access,(double)L2_cache_miss/(double)L2_cache_access); printf("Instruction executed: %llu\n",(long long unsigned)si_count); return; } //printf("cpu.eip is %x in rear cpu-exec.c\n",cpu.eip); //PA 4.4 if(cpu.INTR & eflags.eflags.IF) { //printf("cpu.INTR triggered\n"); uint32_t intr_no = i8259_query_intr(); i8259_ack_intr(); int len = get_instr_len(); cpu.eip --; //TODO: ?! raise_intr(intr_no, len); } } if(nemu_state == RUNNING) { nemu_state = STOP; } }