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

📄 exec.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
    for(i = 0;i < CODE_GEN_PHYS_HASH_SIZE; i++) {        for(tb = tb_phys_hash[i]; tb != NULL; tb = tb->phys_hash_next) {            flags1 = page_get_flags(tb->pc);            flags2 = page_get_flags(tb->pc + tb->size - 1);            if ((flags1 & PAGE_WRITE) || (flags2 & PAGE_WRITE)) {                printf("ERROR page flags: PC=%08lx size=%04x f1=%x f2=%x\n",                       (long)tb->pc, tb->size, flags1, flags2);            }        }    }}void tb_jmp_check(TranslationBlock *tb){    TranslationBlock *tb1;    unsigned int n1;    /* suppress any remaining jumps to this TB */    tb1 = tb->jmp_first;    for(;;) {        n1 = (long)tb1 & 3;        tb1 = (TranslationBlock *)((long)tb1 & ~3);        if (n1 == 2)            break;        tb1 = tb1->jmp_next[n1];    }    /* check end of list */    if (tb1 != tb) {        printf("ERROR: jmp_list from 0x%08lx\n", (long)tb);    }}#endif/* invalidate one TB */static inline void tb_remove(TranslationBlock **ptb, TranslationBlock *tb,                             int next_offset){    TranslationBlock *tb1;    for(;;) {        tb1 = *ptb;        if (tb1 == tb) {            *ptb = *(TranslationBlock **)((char *)tb1 + next_offset);            break;        }        ptb = (TranslationBlock **)((char *)tb1 + next_offset);    }}static inline void tb_page_remove(TranslationBlock **ptb, TranslationBlock *tb){    TranslationBlock *tb1;    unsigned int n1;    for(;;) {        tb1 = *ptb;        n1 = (long)tb1 & 3;        tb1 = (TranslationBlock *)((long)tb1 & ~3);        if (tb1 == tb) {            *ptb = tb1->page_next[n1];            break;        }        ptb = &tb1->page_next[n1];    }}static inline void tb_jmp_remove(TranslationBlock *tb, int n){    TranslationBlock *tb1, **ptb;    unsigned int n1;    ptb = &tb->jmp_next[n];    tb1 = *ptb;    if (tb1) {        /* find tb(n) in circular list */        for(;;) {            tb1 = *ptb;            n1 = (long)tb1 & 3;            tb1 = (TranslationBlock *)((long)tb1 & ~3);            if (n1 == n && tb1 == tb)                break;            if (n1 == 2) {                ptb = &tb1->jmp_first;            } else {                ptb = &tb1->jmp_next[n1];            }        }        /* now we can suppress tb(n) from the list */        *ptb = tb->jmp_next[n];        tb->jmp_next[n] = NULL;    }}/* reset the jump entry 'n' of a TB so that it is not chained to   another TB */static inline void tb_reset_jump(TranslationBlock *tb, int n){    tb_set_jmp_target(tb, n, (unsigned long)(tb->tc_ptr + tb->tb_next_offset[n]));}static inline void tb_phys_invalidate(TranslationBlock *tb, unsigned int page_addr){    CPUState *env;    PageDesc *p;    unsigned int h, n1;    target_ulong phys_pc;    TranslationBlock *tb1, *tb2;    /* remove the TB from the hash list */    phys_pc = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);    h = tb_phys_hash_func(phys_pc);    tb_remove(&tb_phys_hash[h], tb,              offsetof(TranslationBlock, phys_hash_next));    /* remove the TB from the page list */    if (tb->page_addr[0] != page_addr) {        p = page_find(tb->page_addr[0] >> TARGET_PAGE_BITS);        tb_page_remove(&p->first_tb, tb);        invalidate_page_bitmap(p);    }    if (tb->page_addr[1] != -1 && tb->page_addr[1] != page_addr) {        p = page_find(tb->page_addr[1] >> TARGET_PAGE_BITS);        tb_page_remove(&p->first_tb, tb);        invalidate_page_bitmap(p);    }    tb_invalidated_flag = 1;    /* remove the TB from the hash list */    h = tb_jmp_cache_hash_func(tb->pc);    for(env = first_cpu; env != NULL; env = env->next_cpu) {        if (env->tb_jmp_cache[h] == tb)            env->tb_jmp_cache[h] = NULL;    }    /* suppress this TB from the two jump lists */    tb_jmp_remove(tb, 0);    tb_jmp_remove(tb, 1);    /* suppress any remaining jumps to this TB */    tb1 = tb->jmp_first;    for(;;) {        n1 = (long)tb1 & 3;        if (n1 == 2)            break;        tb1 = (TranslationBlock *)((long)tb1 & ~3);        tb2 = tb1->jmp_next[n1];        tb_reset_jump(tb1, n1);        tb1->jmp_next[n1] = NULL;        tb1 = tb2;    }    tb->jmp_first = (TranslationBlock *)((long)tb | 2); /* fail safe */    tb_phys_invalidate_count++;}static inline void set_bits(uint8_t *tab, int start, int len){    int end, mask, end1;    end = start + len;    tab += start >> 3;    mask = 0xff << (start & 7);    if ((start & ~7) == (end & ~7)) {        if (start < end) {            mask &= ~(0xff << (end & 7));            *tab |= mask;        }    } else {        *tab++ |= mask;        start = (start + 8) & ~7;        end1 = end & ~7;        while (start < end1) {            *tab++ = 0xff;            start += 8;        }        if (start < end) {            mask = ~(0xff << (end & 7));            *tab |= mask;        }    }}static void build_page_bitmap(PageDesc *p){    int n, tb_start, tb_end;    TranslationBlock *tb;    p->code_bitmap = qemu_malloc(TARGET_PAGE_SIZE / 8);    if (!p->code_bitmap)        return;    memset(p->code_bitmap, 0, TARGET_PAGE_SIZE / 8);    tb = p->first_tb;    while (tb != NULL) {        n = (long)tb & 3;        tb = (TranslationBlock *)((long)tb & ~3);        /* NOTE: this is subtle as a TB may span two physical pages */        if (n == 0) {            /* NOTE: tb_end may be after the end of the page, but               it is not a problem */            tb_start = tb->pc & ~TARGET_PAGE_MASK;            tb_end = tb_start + tb->size;            if (tb_end > TARGET_PAGE_SIZE)                tb_end = TARGET_PAGE_SIZE;        } else {            tb_start = 0;            tb_end = ((tb->pc + tb->size) & ~TARGET_PAGE_MASK);        }        set_bits(p->code_bitmap, tb_start, tb_end - tb_start);        tb = tb->page_next[n];    }}#ifdef TARGET_HAS_PRECISE_SMCstatic void tb_gen_code(CPUState *env,                        target_ulong pc, target_ulong cs_base, int flags,                        int cflags){    TranslationBlock *tb;    uint8_t *tc_ptr;    target_ulong phys_pc, phys_page2, virt_page2;    int code_gen_size;    phys_pc = get_phys_addr_code(env, pc);    tb = tb_alloc(pc);    if (!tb) {        /* flush must be done */        tb_flush(env);        /* cannot fail at this point */        tb = tb_alloc(pc);    }    tc_ptr = code_gen_ptr;    tb->tc_ptr = tc_ptr;    tb->cs_base = cs_base;    tb->flags = flags;    tb->cflags = cflags;    cpu_gen_code(env, tb, &code_gen_size);    code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));    /* check next page if needed */    virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;    phys_page2 = -1;    if ((pc & TARGET_PAGE_MASK) != virt_page2) {        phys_page2 = get_phys_addr_code(env, virt_page2);    }    tb_link_phys(tb, phys_pc, phys_page2);}#endif/* invalidate all TBs which intersect with the target physical page   starting in range [start;end[. NOTE: start and end must refer to   the same physical page. 'is_cpu_write_access' should be true if called   from a real cpu write access: the virtual CPU will exit the current   TB if code is modified inside this TB. */void tb_invalidate_phys_page_range(target_ulong start, target_ulong end,                                   int is_cpu_write_access){    int n, current_tb_modified, current_tb_not_found, current_flags;    CPUState *env = cpu_single_env;    PageDesc *p;    TranslationBlock *tb, *tb_next, *current_tb, *saved_tb;    target_ulong tb_start, tb_end;    target_ulong current_pc, current_cs_base;    p = page_find(start >> TARGET_PAGE_BITS);    if (!p)        return;    if (!p->code_bitmap &&        ++p->code_write_count >= SMC_BITMAP_USE_THRESHOLD &&        is_cpu_write_access) {        /* build code bitmap */        build_page_bitmap(p);    }    /* we remove all the TBs in the range [start, end[ */    /* XXX: see if in some cases it could be faster to invalidate all the code */    current_tb_not_found = is_cpu_write_access;    current_tb_modified = 0;    current_tb = NULL; /* avoid warning */    current_pc = 0; /* avoid warning */    current_cs_base = 0; /* avoid warning */    current_flags = 0; /* avoid warning */    tb = p->first_tb;    while (tb != NULL) {        n = (long)tb & 3;        tb = (TranslationBlock *)((long)tb & ~3);        tb_next = tb->page_next[n];        /* NOTE: this is subtle as a TB may span two physical pages */        if (n == 0) {            /* NOTE: tb_end may be after the end of the page, but               it is not a problem */            tb_start = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);            tb_end = tb_start + tb->size;        } else {            tb_start = tb->page_addr[1];            tb_end = tb_start + ((tb->pc + tb->size) & ~TARGET_PAGE_MASK);        }        if (!(tb_end <= start || tb_start >= end)) {#ifdef TARGET_HAS_PRECISE_SMC            if (current_tb_not_found) {                current_tb_not_found = 0;                current_tb = NULL;                if (env->mem_write_pc) {                    /* now we have a real cpu fault */                    current_tb = tb_find_pc(env->mem_write_pc);                }            }            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,                                  env->mem_write_pc, NULL);#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 */            /* we need to do that to handle the case where a signal               occurs while doing tb_phys_invalidate() */            saved_tb = NULL;            if (env) {                saved_tb = env->current_tb;                env->current_tb = NULL;            }            tb_phys_invalidate(tb, -1);            if (env) {                env->current_tb = saved_tb;                if (env->interrupt_request && env->current_tb)                    cpu_interrupt(env, env->interrupt_request);            }        }        tb = tb_next;    }#if !defined(CONFIG_USER_ONLY)    /* if no code remaining, no need to continue to use slow writes */    if (!p->first_tb) {        invalidate_page_bitmap(p);        if (is_cpu_write_access) {            tlb_unprotect_code_phys(env, start, env->mem_write_vaddr);        }    }#endif#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, NULL);    }#endif}/* len must be <= 8 and start must be a multiple of len */static inline void tb_invalidate_phys_page_fast(target_ulong start, int len){    PageDesc *p;    int offset, b;#if 0    if (1) {        if (loglevel) {            fprintf(logfile, "modifying code at 0x%x size=%d EIP=%x PC=%08x\n",                   cpu_single_env->mem_write_vaddr, len,                   cpu_single_env->eip,                   cpu_single_env->eip + (long)cpu_single_env->segs[R_CS].base);        }    }#endif    p = page_find(start >> TARGET_PAGE_BITS);    if (!p)        return;    if (p->code_bitmap) {        offset = start & ~TARGET_PAGE_MASK;        b = p->code_bitmap[offset >> 3] >> (offset & 7);        if (b & ((1 << len) - 1))            goto do_invalidate;    } else {    do_invalidate:        tb_invalidate_phys_page_range(start, start + len, 1);    }}#if !defined(CONFIG_SOFTMMU)static void tb_invalidate_phys_page(target_ulong addr,                                    unsigned long pc, void *puc){    int n, current_flags, current_tb_modified;    target_ulong current_pc, current_cs_base;    PageDesc *p;    TranslationBlock *tb, *current_tb;#ifdef TARGET_HAS_PRECISE_SMC

⌨️ 快捷键说明

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