⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 exec.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
    CPUState *env = cpu_single_env;#endif    addr &= TARGET_PAGE_MASK;    p = page_find(addr >> TARGET_PAGE_BITS);    if (!p)        return;    tb = p->first_tb;    current_tb_modified = 0;    current_tb = NULL;    current_pc = 0; /* avoid warning */    current_cs_base = 0; /* avoid warning */    current_flags = 0; /* avoid warning */#ifdef TARGET_HAS_PRECISE_SMC    if (tb && pc != 0) {        current_tb = tb_find_pc(pc);    }#endif    while (tb != NULL) {        n = (long)tb & 3;        tb = (TranslationBlock *)((long)tb & ~3);#ifdef TARGET_HAS_PRECISE_SMC        if (current_tb == tb &&            !(current_tb->cflags & CF_SINGLE_INSN)) {                /* If we are modifying the current TB, we must stop                   its execution. We could be more precise by checking                   that the modification is after the current PC, but it                   would require a specialized function to partially                   restore the CPU state */            current_tb_modified = 1;            cpu_restore_state(current_tb, env, pc, puc);#if defined(TARGET_I386)            current_flags = env->hflags;            current_flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));            current_cs_base = (target_ulong)env->segs[R_CS].base;            current_pc = current_cs_base + env->eip;#else#error unsupported CPU#endif        }#endif /* TARGET_HAS_PRECISE_SMC */        tb_phys_invalidate(tb, addr);        tb = tb->page_next[n];    }    p->first_tb = NULL;#ifdef TARGET_HAS_PRECISE_SMC    if (current_tb_modified) {        /* we generate a block containing just the instruction           modifying the memory. It will ensure that it cannot modify           itself */        env->current_tb = NULL;        tb_gen_code(env, current_pc, current_cs_base, current_flags,                    CF_SINGLE_INSN);        cpu_resume_from_signal(env, puc);    }#endif}#endif/* add the tb in the target page and protect it if necessary */static inline void tb_alloc_page(TranslationBlock *tb,                                 unsigned int n, target_ulong page_addr){    PageDesc *p;    TranslationBlock *last_first_tb;    tb->page_addr[n] = page_addr;    p = page_find_alloc(page_addr >> TARGET_PAGE_BITS);    tb->page_next[n] = p->first_tb;    last_first_tb = p->first_tb;    p->first_tb = (TranslationBlock *)((long)tb | n);    invalidate_page_bitmap(p);#if defined(TARGET_HAS_SMC) || 1#if defined(CONFIG_USER_ONLY)    if (p->flags & PAGE_WRITE) {        target_ulong addr;        PageDesc *p2;        int prot;        /* force the host page as non writable (writes will have a           page fault + mprotect overhead) */        page_addr &= qemu_host_page_mask;        prot = 0;        for(addr = page_addr; addr < page_addr + qemu_host_page_size;            addr += TARGET_PAGE_SIZE) {            p2 = page_find (addr >> TARGET_PAGE_BITS);            if (!p2)                continue;            prot |= p2->flags;            p2->flags &= ~PAGE_WRITE;            page_get_flags(addr);          }        mprotect(g2h(page_addr), qemu_host_page_size,                 (prot & PAGE_BITS) & ~PAGE_WRITE);#ifdef DEBUG_TB_INVALIDATE        printf("protecting code page: 0x" TARGET_FMT_lx "\n",               page_addr);#endif    }#else    /* if some code is already present, then the pages are already       protected. So we handle the case where only the first TB is       allocated in a physical page */    if (!last_first_tb) {        tlb_protect_code(page_addr);    }#endif#endif /* TARGET_HAS_SMC */}/* Allocate a new translation block. Flush the translation buffer if   too many translation blocks or too much generated code. */TranslationBlock *tb_alloc(target_ulong pc){    TranslationBlock *tb;    if (nb_tbs >= CODE_GEN_MAX_BLOCKS ||        (code_gen_ptr - code_gen_buffer) >= CODE_GEN_BUFFER_MAX_SIZE)        return NULL;    tb = &tbs[nb_tbs++];      	    tb->pc = pc;    tb->cflags = 0;    return tb;}/* add a new TB and link it to the physical page tables. phys_page2 is   (-1) to indicate that only one page contains the TB. */void tb_link_phys(TranslationBlock *tb,                  target_ulong phys_pc, target_ulong phys_page2){    unsigned int h;    TranslationBlock **ptb;    /* add in the physical hash table */    h = tb_phys_hash_func(phys_pc);    ptb = &tb_phys_hash[h];    tb->phys_hash_next = *ptb;    *ptb = tb;    /* add in the page list */    tb_alloc_page(tb, 0, phys_pc & TARGET_PAGE_MASK);    if (phys_page2 != -1)        tb_alloc_page(tb, 1, phys_page2);    else        tb->page_addr[1] = -1;    tb->jmp_first = (TranslationBlock *)((long)tb | 2);    tb->jmp_next[0] = NULL;    tb->jmp_next[1] = NULL;    /* init original jump addresses */    if (tb->tb_next_offset[0] != 0xffff)        tb_reset_jump(tb, 0);    if (tb->tb_next_offset[1] != 0xffff)        tb_reset_jump(tb, 1);#ifdef DEBUG_TB_CHECK    tb_page_check();#endif}/* find the TB 'tb' such that tb[0].tc_ptr <= tc_ptr <   tb[1].tc_ptr. Return NULL if not found */TranslationBlock *tb_find_pc(unsigned long tc_ptr){    int m_min, m_max, m;    unsigned long v;    TranslationBlock *tb;    if (nb_tbs <= 0)        return NULL;    if (tc_ptr < (unsigned long)code_gen_buffer ||        tc_ptr >= (unsigned long)code_gen_ptr)        return NULL;    /* binary search (cf Knuth) */    m_min = 0;    m_max = nb_tbs - 1;    while (m_min <= m_max) {        m = (m_min + m_max) >> 1;        tb = &tbs[m];        v = (unsigned long)tb->tc_ptr;        if (v == tc_ptr)            return tb;        else if (tc_ptr < v) {            m_max = m - 1;        } else {            m_min = m + 1;        }    }    return &tbs[m_max];}static void tb_reset_jump_recursive(TranslationBlock *tb);static inline void tb_reset_jump_recursive2(TranslationBlock *tb, int n){    TranslationBlock *tb1, *tb_next, **ptb;    unsigned int n1;    tb1 = tb->jmp_next[n];    if (tb1 != NULL) {        /* find head of list */        for(;;) {            n1 = (long)tb1 & 3;            tb1 = (TranslationBlock *)((long)tb1 & ~3);            if (n1 == 2)                break;            tb1 = tb1->jmp_next[n1];        }        /* we are now sure now that tb jumps to tb1 */        tb_next = tb1;        /* remove tb from the jmp_first list */        ptb = &tb_next->jmp_first;        for(;;) {            tb1 = *ptb;            n1 = (long)tb1 & 3;            tb1 = (TranslationBlock *)((long)tb1 & ~3);            if (n1 == n && tb1 == tb)                break;            ptb = &tb1->jmp_next[n1];        }        *ptb = tb->jmp_next[n];        tb->jmp_next[n] = NULL;        /* suppress the jump to next tb in generated code */        tb_reset_jump(tb, n);        /* suppress jumps in the tb on which we could have jumped */        tb_reset_jump_recursive(tb_next);    }}static void tb_reset_jump_recursive(TranslationBlock *tb)//这里是个点{    tb_reset_jump_recursive2(tb, 0);    tb_reset_jump_recursive2(tb, 1);}#if defined(TARGET_HAS_ICE)static void breakpoint_invalidate(CPUState *env, target_ulong pc){    target_phys_addr_t addr;    target_ulong pd;    ram_addr_t ram_addr;    PhysPageDesc *p;    addr = cpu_get_phys_page_debug(env, pc);    p = phys_page_find(addr >> TARGET_PAGE_BITS);    if (!p) {        pd = IO_MEM_UNASSIGNED;    } else {        pd = p->phys_offset;    }    ram_addr = (pd & TARGET_PAGE_MASK) | (pc & ~TARGET_PAGE_MASK);    tb_invalidate_phys_page_range(ram_addr, ram_addr + 1, 0);}#endif/* Add a watchpoint.  */int  cpu_watchpoint_insert(CPUState *env, target_ulong addr){    int i;    for (i = 0; i < env->nb_watchpoints; i++) {        if (addr == env->watchpoint[i].vaddr)            return 0;    }    if (env->nb_watchpoints >= MAX_WATCHPOINTS)        return -1;    i = env->nb_watchpoints++;    env->watchpoint[i].vaddr = addr;    tlb_flush_page(env, addr);    /* FIXME: This flush is needed because of the hack to make memory ops       terminate the TB.  It can be removed once the proper IO trap and       re-execute bits are in.  */    tb_flush(env);    return i;}/* Remove a watchpoint.  */int cpu_watchpoint_remove(CPUState *env, target_ulong addr){    int i;    for (i = 0; i < env->nb_watchpoints; i++) {        if (addr == env->watchpoint[i].vaddr) {            env->nb_watchpoints--;            env->watchpoint[i] = env->watchpoint[env->nb_watchpoints];            tlb_flush_page(env, addr);            return 0;        }    }    return -1;}/* add a breakpoint. EXCP_DEBUG is returned by the CPU loop if a   breakpoint is reached */int cpu_breakpoint_insert(CPUState *env, target_ulong pc){#if defined(TARGET_HAS_ICE)    int i;    for(i = 0; i < env->nb_breakpoints; i++) {        if (env->breakpoints[i] == pc)            return 0;    }    if (env->nb_breakpoints >= MAX_BREAKPOINTS)        return -1;    env->breakpoints[env->nb_breakpoints++] = pc;    breakpoint_invalidate(env, pc);    return 0;#else    return -1;#endif}/* remove a breakpoint */int cpu_breakpoint_remove(CPUState *env, target_ulong pc){#if defined(TARGET_HAS_ICE)    int i;    for(i = 0; i < env->nb_breakpoints; i++) {        if (env->breakpoints[i] == pc)            goto found;    }    return -1; found:    env->nb_breakpoints--;    if (i < env->nb_breakpoints)      env->breakpoints[i] = env->breakpoints[env->nb_breakpoints];    breakpoint_invalidate(env, pc);    return 0;#else    return -1;#endif}/* enable or disable single step mode. EXCP_DEBUG is returned by the   CPU loop after each instruction */void cpu_single_step(CPUState *env, int enabled){#if defined(TARGET_HAS_ICE)    if (env->singlestep_enabled != enabled) {        env->singlestep_enabled = enabled;        /* must flush all the translated code to avoid inconsistancies */        /* XXX: only flush what is necessary */        tb_flush(env);    }#endif}/* enable or disable low levels log */void cpu_set_log(int log_flags){    loglevel = log_flags;    if (loglevel && !logfile) {        logfile = fopen(logfilename, log_append ? "a" : "w");        if (!logfile) {            perror(logfilename);            _exit(1);        }#if !defined(CONFIG_SOFTMMU)        /* must avoid mmap() usage of glibc by setting a buffer "by hand" */        {            static uint8_t logfile_buf[4096];            setvbuf(logfile, logfile_buf, _IOLBF, sizeof(logfile_buf));        }#else        setvbuf(logfile, NULL, _IOLBF, 0);#endif        log_append = 1;    }    if (!loglevel && logfile) {        fclose(logfile);        logfile = NULL;    }}void cpu_set_log_filename(const char *filename){    logfilename = strdup(filename);    if (logfile) {        fclose(logfile);        logfile = NULL;    }    cpu_set_log(loglevel);}/* mask must never be zero, except for A20 change call */void cpu_interrupt(CPUState *env, int mask){    TranslationBlock *tb;    static int interrupt_lock;    env->interrupt_request |= mask;    /* if the cpu is currently executing code, we must unlink it and

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -