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

📄 helper.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 2 页
字号:
            /* Lookup l2 entry.  */            table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);            desc = ldl_phys(table);            switch (desc & 3) {            case 0: /* Page translation fault.  */                code = 7;                goto do_fault;            case 1: /* 64k page.  */                phys_addr = (desc & 0xffff0000) | (address & 0xffff);                ap = (desc >> (4 + ((address >> 13) & 6))) & 3;                break;            case 2: /* 4k page.  */                phys_addr = (desc & 0xfffff000) | (address & 0xfff);                ap = (desc >> (4 + ((address >> 13) & 6))) & 3;                break;            case 3: /* 1k page.  */                if (type == 1) {                    /* Page translation fault.  */                    code = 7;                    goto do_fault;                }                phys_addr = (desc & 0xfffffc00) | (address & 0x3ff);                ap = (desc >> 4) & 3;                break;            default:                /* Never happens, but compiler isn't smart enough to tell.  */                abort();            }            code = 15;        }        *prot = check_ap(env, ap, domain, access_type, is_user);        if (!*prot) {            /* Access permission fault.  */            goto do_fault;        }        *phys_ptr = phys_addr;    }    return 0;do_fault:    return code | (domain << 4);}int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address,                              int access_type, int is_user, int is_softmmu){    uint32_t phys_addr;    int prot;    int ret;    ret = get_phys_addr(env, address, access_type, is_user, &phys_addr, &prot);    if (ret == 0) {        /* Map a single [sub]page.  */        phys_addr &= ~(uint32_t)0x3ff;        address &= ~(uint32_t)0x3ff;        return tlb_set_page (env, address, phys_addr, prot, is_user,                             is_softmmu);    }    if (access_type == 2) {        env->cp15.c5_insn = ret;        env->cp15.c6_insn = address;        env->exception_index = EXCP_PREFETCH_ABORT;    } else {        env->cp15.c5_data = ret;        env->cp15.c6_data = address;        env->exception_index = EXCP_DATA_ABORT;    }    return 1;}target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr){    uint32_t phys_addr;    int prot;    int ret;    ret = get_phys_addr(env, addr, 0, 0, &phys_addr, &prot);    if (ret != 0)        return -1;    return phys_addr;}void helper_set_cp15(CPUState *env, uint32_t insn, uint32_t val){    uint32_t op2;    op2 = (insn >> 5) & 7;    switch ((insn >> 16) & 0xf) {    case 0: /* ID codes.  */        goto bad_reg;    case 1: /* System configuration.  */        switch (op2) {        case 0:            env->cp15.c1_sys = val;            /* ??? Lots of these bits are not implemented.  */            /* This may enable/disable the MMU, so do a TLB flush.  */            tlb_flush(env, 1);            break;        case 2:            env->cp15.c1_coproc = val;            /* ??? Is this safe when called from within a TB?  */            tb_flush(env);        default:            goto bad_reg;        }        break;    case 2: /* MMU Page table control.  */        env->cp15.c2 = val;        break;    case 3: /* MMU Domain access control.  */        env->cp15.c3 = val;        break;    case 4: /* Reserved.  */        goto bad_reg;    case 5: /* MMU Fault status.  */        switch (op2) {        case 0:            env->cp15.c5_data = val;            break;        case 1:            env->cp15.c5_insn = val;            break;        default:            goto bad_reg;        }        break;    case 6: /* MMU Fault address.  */        switch (op2) {        case 0:            env->cp15.c6_data = val;            break;        case 1:            env->cp15.c6_insn = val;            break;        default:            goto bad_reg;        }        break;    case 7: /* Cache control.  */        /* No cache, so nothing to do.  */        break;    case 8: /* MMU TLB control.  */        switch (op2) {        case 0: /* Invalidate all.  */            tlb_flush(env, 0);            break;        case 1: /* Invalidate single TLB entry.  */#if 0            /* ??? This is wrong for large pages and sections.  */            /* As an ugly hack to make linux work we always flush a 4K               pages.  */            val &= 0xfffff000;            tlb_flush_page(env, val);            tlb_flush_page(env, val + 0x400);            tlb_flush_page(env, val + 0x800);            tlb_flush_page(env, val + 0xc00);#else            tlb_flush(env, 1);#endif            break;        default:            goto bad_reg;        }        break;    case 9: /* Cache lockdown.  */        switch (op2) {        case 0:            env->cp15.c9_data = val;            break;        case 1:            env->cp15.c9_insn = val;            break;        default:            goto bad_reg;        }        break;    case 10: /* MMU TLB lockdown.  */        /* ??? TLB lockdown not implemented.  */        break;    case 11: /* TCM DMA control.  */    case 12: /* Reserved.  */        goto bad_reg;    case 13: /* Process ID.  */        switch (op2) {        case 0:            env->cp15.c9_data = val;            break;        case 1:            env->cp15.c9_insn = val;            break;        default:            goto bad_reg;        }        break;    case 14: /* Reserved.  */        goto bad_reg;    case 15: /* Implementation specific.  */        /* ??? Internal registers not implemented.  */        break;    }    return;bad_reg:    /* ??? For debugging only.  Should raise illegal instruction exception.  */    cpu_abort(env, "Unimplemented cp15 register read\n");}uint32_t helper_get_cp15(CPUState *env, uint32_t insn){    uint32_t op2;    op2 = (insn >> 5) & 7;    switch ((insn >> 16) & 0xf) {    case 0: /* ID codes.  */        switch (op2) {        default: /* Device ID.  */            return env->cp15.c0_cpuid;        case 1: /* Cache Type.  */            return 0x1dd20d2;        case 2: /* TCM status.  */            return 0;        }    case 1: /* System configuration.  */        switch (op2) {        case 0: /* Control register.  */            return env->cp15.c1_sys;        case 1: /* Auxiliary control register.  */            if (arm_feature(env, ARM_FEATURE_AUXCR))                return 1;            goto bad_reg;        case 2: /* Coprocessor access register.  */            return env->cp15.c1_coproc;        default:            goto bad_reg;        }    case 2: /* MMU Page table control.  */        return env->cp15.c2;    case 3: /* MMU Domain access control.  */        return env->cp15.c3;    case 4: /* Reserved.  */        goto bad_reg;    case 5: /* MMU Fault status.  */        switch (op2) {        case 0:            return env->cp15.c5_data;        case 1:            return env->cp15.c5_insn;        default:            goto bad_reg;        }    case 6: /* MMU Fault address.  */        switch (op2) {        case 0:            return env->cp15.c6_data;        case 1:            /* Arm9 doesn't have an IFAR, but implementing it anyway shouldn't               do any harm.  */            return env->cp15.c6_insn;        default:            goto bad_reg;        }    case 7: /* Cache control.  */        /* ??? This is for test, clean and invaidate operations that set the           Z flag.  We can't represent N = Z = 1, so it also clears clears           the N flag.  Oh well.  */        env->NZF = 0;        return 0;    case 8: /* MMU TLB control.  */        goto bad_reg;    case 9: /* Cache lockdown.  */        switch (op2) {        case 0:            return env->cp15.c9_data;        case 1:            return env->cp15.c9_insn;        default:            goto bad_reg;        }    case 10: /* MMU TLB lockdown.  */        /* ??? TLB lockdown not implemented.  */        return 0;    case 11: /* TCM DMA control.  */    case 12: /* Reserved.  */        goto bad_reg;    case 13: /* Process ID.  */        switch (op2) {        case 0:            return env->cp15.c13_fcse;        case 1:            return env->cp15.c13_context;        default:            goto bad_reg;        }    case 14: /* Reserved.  */        goto bad_reg;    case 15: /* Implementation specific.  */        /* ??? Internal registers not implemented.  */        return 0;    }bad_reg:    /* ??? For debugging only.  Should raise illegal instruction exception.  */    cpu_abort(env, "Unimplemented cp15 register read\n");    return 0;}#endif

⌨️ 快捷键说明

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