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

📄 helper.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
            code = 9; /* Section domain fault.  */        else            code = 11; /* Page domain fault.  */        goto do_fault;    }    if (type == 2) {        if (desc & (1 << 18)) {            /* Supersection.  */            phys_addr = (desc & 0xff000000) | (address & 0x00ffffff);        } else {            /* Section.  */            phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);        }        ap = ((desc >> 10) & 3) | ((desc >> 13) & 4);        xn = desc & (1 << 4);        code = 13;    } else {        /* Lookup l2 entry.  */        table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);        desc = ldl_phys(table);        ap = ((desc >> 4) & 3) | ((desc >> 7) & 4);        switch (desc & 3) {        case 0: /* Page translation fault.  */            code = 7;            goto do_fault;        case 1: /* 64k page.  */            phys_addr = (desc & 0xffff0000) | (address & 0xffff);            xn = desc & (1 << 15);            break;        case 2: case 3: /* 4k page.  */            phys_addr = (desc & 0xfffff000) | (address & 0xfff);            xn = desc & 1;            break;        default:            /* Never happens, but compiler isn't smart enough to tell.  */            abort();        }        code = 15;    }    if (xn && access_type == 2)        goto do_fault;    *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);}static int get_phys_addr_mpu(CPUState *env, uint32_t address, int access_type,			     int is_user, uint32_t *phys_ptr, int *prot){    int n;    uint32_t mask;    uint32_t base;    *phys_ptr = address;    for (n = 7; n >= 0; n--) {	base = env->cp15.c6_region[n];	if ((base & 1) == 0)	    continue;	mask = 1 << ((base >> 1) & 0x1f);	/* Keep this shift separate from the above to avoid an	   (undefined) << 32.  */	mask = (mask << 1) - 1;	if (((base ^ address) & ~mask) == 0)	    break;    }    if (n < 0)	return 2;    if (access_type == 2) {	mask = env->cp15.c5_insn;    } else {	mask = env->cp15.c5_data;    }    mask = (mask >> (n * 4)) & 0xf;    switch (mask) {    case 0:	return 1;    case 1:	if (is_user)	  return 1;	*prot = PAGE_READ | PAGE_WRITE;	break;    case 2:	*prot = PAGE_READ;	if (!is_user)	    *prot |= PAGE_WRITE;	break;    case 3:	*prot = PAGE_READ | PAGE_WRITE;	break;    case 5:	if (is_user)	    return 1;	*prot = PAGE_READ;	break;    case 6:	*prot = PAGE_READ;	break;    default:	/* Bad permission.  */	return 1;    }    return 0;}static inline int get_phys_addr(CPUState *env, uint32_t address,                                int access_type, int is_user,                                uint32_t *phys_ptr, int *prot){    /* Fast Context Switch Extension.  */    if (address < 0x02000000)        address += env->cp15.c13_fcse;    if ((env->cp15.c1_sys & 1) == 0) {        /* MMU/MPU disabled.  */        *phys_ptr = address;        *prot = PAGE_READ | PAGE_WRITE;        return 0;    } else if (arm_feature(env, ARM_FEATURE_MPU)) {	return get_phys_addr_mpu(env, address, access_type, is_user, phys_ptr,				 prot);    } else if (env->cp15.c1_sys & (1 << 23)) {        return get_phys_addr_v6(env, address, access_type, is_user, phys_ptr,                                prot);    } else {        return get_phys_addr_v5(env, address, access_type, is_user, phys_ptr,                                prot);    }}int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address,                              int access_type, int mmu_idx, int is_softmmu){    uint32_t phys_addr;    int prot;    int ret, is_user;    is_user = mmu_idx == MMU_USER_IDX;    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, mmu_idx,                             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;        if (access_type == 1 && arm_feature(env, ARM_FEATURE_V6))            env->cp15.c5_data |= (1 << 11);        env->cp15.c6_data = address;        env->exception_index = EXCP_DATA_ABORT;    }    return 1;}target_phys_addr_t 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;}/* Not really implemented.  Need to figure out a sane way of doing this.   Maybe add generic watchpoint support and use that.  */void helper_mark_exclusive(CPUState *env, uint32_t addr){    env->mmon_addr = addr;}int helper_test_exclusive(CPUState *env, uint32_t addr){    return (env->mmon_addr != addr);}void helper_clrex(CPUState *env){    env->mmon_addr = -1;}void helper_set_cp(CPUState *env, uint32_t insn, uint32_t val){    int cp_num = (insn >> 8) & 0xf;    int cp_info = (insn >> 5) & 7;    int src = (insn >> 16) & 0xf;    int operand = insn & 0xf;    if (env->cp[cp_num].cp_write)        env->cp[cp_num].cp_write(env->cp[cp_num].opaque,                                 cp_info, src, operand, val);}uint32_t helper_get_cp(CPUState *env, uint32_t insn){    int cp_num = (insn >> 8) & 0xf;    int cp_info = (insn >> 5) & 7;    int dest = (insn >> 16) & 0xf;    int operand = insn & 0xf;    if (env->cp[cp_num].cp_read)        return env->cp[cp_num].cp_read(env->cp[cp_num].opaque,                                       cp_info, dest, operand);    return 0;}/* Return basic MPU access permission bits.  */static uint32_t simple_mpu_ap_bits(uint32_t val){    uint32_t ret;    uint32_t mask;    int i;    ret = 0;    mask = 3;    for (i = 0; i < 16; i += 2) {        ret |= (val >> i) & mask;        mask <<= 2;    }    return ret;}/* Pad basic MPU access permission bits to extended format.  */static uint32_t extended_mpu_ap_bits(uint32_t val){    uint32_t ret;    uint32_t mask;    int i;    ret = 0;    mask = 3;    for (i = 0; i < 16; i += 2) {        ret |= (val & mask) << i;        mask <<= 2;    }    return ret;}void helper_set_cp15(CPUState *env, uint32_t insn, uint32_t val){    int op1;    int op2;    int crm;    op1 = (insn >> 21) & 7;    op2 = (insn >> 5) & 7;    crm = insn & 0xf;    switch ((insn >> 16) & 0xf) {    case 0:        if (((insn >> 21) & 7) == 2) {            /* ??? Select cache level.  Ignore.  */            return;        }        /* ID codes.  */        if (arm_feature(env, ARM_FEATURE_XSCALE))            break;        if (arm_feature(env, ARM_FEATURE_OMAPCP))            break;        goto bad_reg;    case 1: /* System configuration.  */        if (arm_feature(env, ARM_FEATURE_OMAPCP))            op2 = 0;        switch (op2) {        case 0:            if (!arm_feature(env, ARM_FEATURE_XSCALE) || crm == 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 1: /* Auxiliary cotrol register.  */            if (arm_feature(env, ARM_FEATURE_XSCALE)) {                env->cp15.c1_xscaleauxcr = val;                break;            }            /* Not implemented.  */            break;        case 2:            if (arm_feature(env, ARM_FEATURE_XSCALE))                goto bad_reg;            env->cp15.c1_coproc = val;            /* ??? Is this safe when called from within a TB?  */            tb_flush(env);            break;        default:            goto bad_reg;        }        break;    case 2: /* MMU Page table control / MPU cache control.  */        if (arm_feature(env, ARM_FEATURE_MPU)) {            switch (op2) {            case 0:                env->cp15.c2_data = val;                break;            case 1:                env->cp15.c2_insn = val;                break;            default:                goto bad_reg;            }        } else {	    switch (op2) {	    case 0:		env->cp15.c2_base0 = val;		break;	    case 1:		env->cp15.c2_base1 = val;		break;	    case 2:		env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> val);		break;	    default:		goto bad_reg;	    }        }        break;    case 3: /* MMU Domain access control / MPU write buffer control.  */        env->cp15.c3 = val;        tlb_flush(env, 1); /* Flush TLB as domain not tracked in TLB */        break;    case 4: /* Reserved.  */        goto bad_reg;    case 5: /* MMU Fault status / MPU access permission.  */        if (arm_feature(env, ARM_FEATURE_OMAPCP))            op2 = 0;        switch (op2) {        case 0:            if (arm_feature(env, ARM_FEATURE_MPU))                val = extended_mpu_ap_bits(val);            env->cp15.c5_data = val;            break;        case 1:            if (arm_feature(env, ARM_FEATURE_MPU))                val = extended_mpu_ap_bits(val);            env->cp15.c5_insn = val;            break;        case 2:            if (!arm_feature(env, ARM_FEATURE_MPU))                goto bad_reg;            env->cp15.c5_data = val;            break;        case 3:            if (!arm_feature(env, ARM_FEATURE_MPU))                goto bad_reg;            env->cp15.c5_insn = val;            break;        default:            goto bad_reg;        }        break;    case 6: /* MMU Fault address / MPU base/size.  */        if (arm_feature(env, ARM_FEATURE_MPU)) {            if (crm >= 8)                goto bad_reg;            env->cp15.c6_region[crm] = val;        } else {            if (arm_feature(env, ARM_FEATURE_OMAPCP))                op2 = 0;            switch (op2) {            case 0:                env->cp15.c6_data = val;                break;            case 1: /* ??? This is WFAR on armv6 */            case 2:                env->cp15.c6_insn = val;                break;            default:                goto bad_reg;            }        }        break;    case 7: /* Cache control.  */        env->cp15.c15_i_max = 0x000;        env->cp15.c15_i_min = 0xff0;        /* No cache, so nothing to do.  */        /* ??? MPCore has VA to PA translation functions.  */        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;        case 2: /* Invalidate on ASID.  */            tlb_flush(env, val == 0);            break;        case 3: /* Invalidate single entry on MVA.  */            /* ??? This is like case 1, but ignores ASID.  */            tlb_flush(env, 1);            break;        default:            goto bad_reg;        }        break;    case 9:        if (arm_feature(env, ARM_FEATURE_OMAPCP))            break;        switch (crm) {        case 0: /* Cache lockdown.  */	    switch (op1) {	    case 0: /* L1 cache.  */		switch (op2) {		case 0:		    env->cp15.c9_data = val;		    break;		case 1:		    env->cp15.c9_insn = val;		    break;		default:		    goto bad_reg;		}		break;	    case 1: /* L2 cache.  */		/* Ignore writes to L2 lockdown/auxiliary registers.  */		break;	    default:		goto bad_reg;	    }	    break;        case 1: /* TCM memory region registers.  */            /* Not implemented.  */            goto bad_reg;        default:            goto bad_reg;        }        break;    case 10: /* MMU TLB lockdown.  */        /* ??? TLB lockdown not implemented.  */        break;    case 12: /* Reserved.  */        goto bad_reg;    case 13: /* Process ID.  */        switch (op2) {        case 0:            /* Unlike real hardware the qemu TLB uses virtual addresses,               not modified virtual addresses, so this causes a TLB flush.

⌨️ 快捷键说明

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