helper.c

来自「xen虚拟机源代码安装包」· C语言 代码 · 共 1,349 行 · 第 1/3 页

C
1,349
字号
    return 1;}static int get_physical_address_code(CPUState *env,                                     target_phys_addr_t *physical, int *prot,                                     target_ulong address, int is_user){    target_ulong mask;    unsigned int i;    if ((env->lsu & IMMU_E) == 0) { /* IMMU disabled */        *physical = address;        *prot = PAGE_EXEC;        return 0;    }    for (i = 0; i < 64; i++) {        switch ((env->itlb_tte[i] >> 61) & 3) {        default:        case 0x0: // 8k            mask = 0xffffffffffffe000ULL;            break;        case 0x1: // 64k            mask = 0xffffffffffff0000ULL;            break;        case 0x2: // 512k            mask = 0xfffffffffff80000ULL;            break;        case 0x3: // 4M            mask = 0xffffffffffc00000ULL;                break;        }        // ctx match, vaddr match?        if (env->dmmuregs[1] == (env->itlb_tag[i] & 0x1fff) &&            (address & mask) == (env->itlb_tag[i] & ~0x1fffULL)) {            // valid, access ok?            if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0 ||                ((env->itlb_tte[i] & 0x4) && is_user)) {                if (env->immuregs[3]) /* Fault status register */                    env->immuregs[3] = 2; /* overflow (not read before                                             another fault) */                env->immuregs[3] |= (is_user << 3) | 1;                env->exception_index = TT_TFAULT;#ifdef DEBUG_MMU                printf("TFAULT at 0x%" PRIx64 "\n", address);#endif                return 1;            }            *physical = (env->itlb_tte[i] & mask & 0x1fffffff000ULL) +                (address & ~mask & 0x1fffffff000ULL);            *prot = PAGE_EXEC;            return 0;        }    }#ifdef DEBUG_MMU    printf("TMISS at 0x%" PRIx64 "\n", address);#endif    env->exception_index = TT_TMISS;    return 1;}static int get_physical_address(CPUState *env, target_phys_addr_t *physical,                                int *prot, int *access_index,                                target_ulong address, int rw, int mmu_idx){    int is_user = mmu_idx == MMU_USER_IDX;    if (rw == 2)        return get_physical_address_code(env, physical, prot, address,                                         is_user);    else        return get_physical_address_data(env, physical, prot, address, rw,                                         is_user);}/* Perform address translation */int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,                              int mmu_idx, int is_softmmu){    target_ulong virt_addr, vaddr;    target_phys_addr_t paddr;    int error_code = 0, prot, ret = 0, access_index;    error_code = get_physical_address(env, &paddr, &prot, &access_index,                                      address, rw, mmu_idx);    if (error_code == 0) {        virt_addr = address & TARGET_PAGE_MASK;        vaddr = virt_addr + ((address & TARGET_PAGE_MASK) &                             (TARGET_PAGE_SIZE - 1));#ifdef DEBUG_MMU        printf("Translate at 0x%" PRIx64 " -> 0x%" PRIx64 ", vaddr 0x%" PRIx64               "\n", address, paddr, vaddr);#endif        ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);        return ret;    }    // XXX    return 1;}#ifdef DEBUG_MMUvoid dump_mmu(CPUState *env){    unsigned int i;    const char *mask;    printf("MMU contexts: Primary: %" PRId64 ", Secondary: %" PRId64 "\n",           env->dmmuregs[1], env->dmmuregs[2]);    if ((env->lsu & DMMU_E) == 0) {        printf("DMMU disabled\n");    } else {        printf("DMMU dump:\n");        for (i = 0; i < 64; i++) {            switch ((env->dtlb_tte[i] >> 61) & 3) {            default:            case 0x0:                mask = "  8k";                break;            case 0x1:                mask = " 64k";                break;            case 0x2:                mask = "512k";                break;            case 0x3:                mask = "  4M";                break;            }            if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0) {                printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx                       ", %s, %s, %s, %s, ctx %" PRId64 "\n",                       env->dtlb_tag[i] & ~0x1fffULL,                       env->dtlb_tte[i] & 0x1ffffffe000ULL,                       mask,                       env->dtlb_tte[i] & 0x4? "priv": "user",                       env->dtlb_tte[i] & 0x2? "RW": "RO",                       env->dtlb_tte[i] & 0x40? "locked": "unlocked",                       env->dtlb_tag[i] & 0x1fffULL);            }        }    }    if ((env->lsu & IMMU_E) == 0) {        printf("IMMU disabled\n");    } else {        printf("IMMU dump:\n");        for (i = 0; i < 64; i++) {            switch ((env->itlb_tte[i] >> 61) & 3) {            default:            case 0x0:                mask = "  8k";                break;            case 0x1:                mask = " 64k";                break;            case 0x2:                mask = "512k";                break;            case 0x3:                mask = "  4M";                break;            }            if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0) {                printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx                       ", %s, %s, %s, ctx %" PRId64 "\n",                       env->itlb_tag[i] & ~0x1fffULL,                       env->itlb_tte[i] & 0x1ffffffe000ULL,                       mask,                       env->itlb_tte[i] & 0x4? "priv": "user",                       env->itlb_tte[i] & 0x40? "locked": "unlocked",                       env->itlb_tag[i] & 0x1fffULL);            }        }    }}#endif /* DEBUG_MMU */#endif /* TARGET_SPARC64 */#endif /* !CONFIG_USER_ONLY */#if defined(CONFIG_USER_ONLY)target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr){    return addr;}#elsetarget_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr){    target_phys_addr_t phys_addr;    int prot, access_index;    if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2,                             MMU_KERNEL_IDX) != 0)        if (get_physical_address(env, &phys_addr, &prot, &access_index, addr,                                 0, MMU_KERNEL_IDX) != 0)            return -1;    if (cpu_get_physical_page_desc(phys_addr) == IO_MEM_UNASSIGNED)        return -1;    return phys_addr;}#endifvoid memcpy32(target_ulong *dst, const target_ulong *src){    dst[0] = src[0];    dst[1] = src[1];    dst[2] = src[2];    dst[3] = src[3];    dst[4] = src[4];    dst[5] = src[5];    dst[6] = src[6];    dst[7] = src[7];}void helper_flush(target_ulong addr){    addr &= ~7;    tb_invalidate_page_range(addr, addr + 8);}void cpu_reset(CPUSPARCState *env){    tlb_flush(env, 1);    env->cwp = 0;    env->wim = 1;    env->regwptr = env->regbase + (env->cwp * 16);#if defined(CONFIG_USER_ONLY)    env->user_mode_only = 1;#ifdef TARGET_SPARC64    env->cleanwin = NWINDOWS - 2;    env->cansave = NWINDOWS - 2;    env->pstate = PS_RMO | PS_PEF | PS_IE;    env->asi = 0x82; // Primary no-fault#endif#else    env->psret = 0;    env->psrs = 1;    env->psrps = 1;#ifdef TARGET_SPARC64    env->pstate = PS_PRIV;    env->hpstate = HS_PRIV;    env->pc = 0x1fff0000000ULL;    env->tsptr = &env->ts[env->tl];#else    env->pc = 0;    env->mmuregs[0] &= ~(MMU_E | MMU_NF);    env->mmuregs[0] |= env->mmu_bm;#endif    env->npc = env->pc + 4;#endif}static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model){    sparc_def_t def1, *def = &def1;    if (cpu_sparc_find_by_name(def, cpu_model) < 0)        return -1;    env->features = def->features;    env->cpu_model_str = cpu_model;    env->version = def->iu_version;    env->fsr = def->fpu_version;#if !defined(TARGET_SPARC64)    env->mmu_bm = def->mmu_bm;    env->mmu_ctpr_mask = def->mmu_ctpr_mask;    env->mmu_cxr_mask = def->mmu_cxr_mask;    env->mmu_sfsr_mask = def->mmu_sfsr_mask;    env->mmu_trcr_mask = def->mmu_trcr_mask;    env->mmuregs[0] |= def->mmu_version;    cpu_sparc_set_id(env, 0);#endif    return 0;}static void cpu_sparc_close(CPUSPARCState *env){    free(env);}CPUSPARCState *cpu_sparc_init(const char *cpu_model){    CPUSPARCState *env;    env = qemu_mallocz(sizeof(CPUSPARCState));    if (!env)        return NULL;    cpu_exec_init(env);    gen_intermediate_code_init(env);    if (cpu_sparc_register(env, cpu_model) < 0) {        cpu_sparc_close(env);        return NULL;    }    cpu_reset(env);    return env;}void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu){#if !defined(TARGET_SPARC64)    env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;#endif}static const sparc_def_t sparc_defs[] = {#ifdef TARGET_SPARC64    {        .name = "Fujitsu Sparc64",        .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)                       | (MAXTL << 8) | (NWINDOWS - 1)),        .fpu_version = 0x00000000,        .mmu_version = 0,        .features = CPU_DEFAULT_FEATURES,    },    {        .name = "Fujitsu Sparc64 III",        .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)                       | (MAXTL << 8) | (NWINDOWS - 1)),        .fpu_version = 0x00000000,        .mmu_version = 0,        .features = CPU_DEFAULT_FEATURES,    },    {        .name = "Fujitsu Sparc64 IV",        .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)                       | (MAXTL << 8) | (NWINDOWS - 1)),        .fpu_version = 0x00000000,        .mmu_version = 0,        .features = CPU_DEFAULT_FEATURES,    },    {        .name = "Fujitsu Sparc64 V",        .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)                       | (MAXTL << 8) | (NWINDOWS - 1)),        .fpu_version = 0x00000000,        .mmu_version = 0,        .features = CPU_DEFAULT_FEATURES,    },    {        .name = "TI UltraSparc I",        .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)                       | (MAXTL << 8) | (NWINDOWS - 1)),        .fpu_version = 0x00000000,        .mmu_version = 0,        .features = CPU_DEFAULT_FEATURES,    },    {        .name = "TI UltraSparc II",        .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)                       | (MAXTL << 8) | (NWINDOWS - 1)),        .fpu_version = 0x00000000,        .mmu_version = 0,        .features = CPU_DEFAULT_FEATURES,    },    {        .name = "TI UltraSparc IIi",        .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)                       | (MAXTL << 8) | (NWINDOWS - 1)),        .fpu_version = 0x00000000,        .mmu_version = 0,        .features = CPU_DEFAULT_FEATURES,    },    {        .name = "TI UltraSparc IIe",        .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)                       | (MAXTL << 8) | (NWINDOWS - 1)),        .fpu_version = 0x00000000,        .mmu_version = 0,        .features = CPU_DEFAULT_FEATURES,    },    {        .name = "Sun UltraSparc III",        .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)                       | (MAXTL << 8) | (NWINDOWS - 1)),        .fpu_version = 0x00000000,        .mmu_version = 0,        .features = CPU_DEFAULT_FEATURES,    },    {        .name = "Sun UltraSparc III Cu",        .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)                       | (MAXTL << 8) | (NWINDOWS - 1)),        .fpu_version = 0x00000000,        .mmu_version = 0,        .features = CPU_DEFAULT_FEATURES,    },    {        .name = "Sun UltraSparc IIIi",        .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)                       | (MAXTL << 8) | (NWINDOWS - 1)),        .fpu_version = 0x00000000,        .mmu_version = 0,        .features = CPU_DEFAULT_FEATURES,    },    {        .name = "Sun UltraSparc IV",        .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)                       | (MAXTL << 8) | (NWINDOWS - 1)),        .fpu_version = 0x00000000,        .mmu_version = 0,        .features = CPU_DEFAULT_FEATURES,    },    {        .name = "Sun UltraSparc IV+",        .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)                       | (MAXTL << 8) | (NWINDOWS - 1)),        .fpu_version = 0x00000000,        .mmu_version = 0,        .features = CPU_DEFAULT_FEATURES,    },    {        .name = "Sun UltraSparc IIIi+",        .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)                       | (MAXTL << 8) | (NWINDOWS - 1)),        .fpu_version = 0x00000000,        .mmu_version = 0,        .features = CPU_DEFAULT_FEATURES,    },    {        .name = "NEC UltraSparc I",        .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)                       | (MAXTL << 8) | (NWINDOWS - 1)),        .fpu_version = 0x00000000,        .mmu_version = 0,        .features = CPU_DEFAULT_FEATURES,    },#else    {        .name = "Fujitsu MB86900",        .iu_version = 0x00 << 24, /* Impl 0, ver 0 */        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */        .mmu_version = 0x00 << 24, /* Impl 0, ver 0 */        .mmu_bm = 0x00004000,        .mmu_ctpr_mask = 0x007ffff0,        .mmu_cxr_mask = 0x0000003f,        .mmu_sfsr_mask = 0xffffffff,        .mmu_trcr_mask = 0xffffffff,        .features = CPU_FEATURE_FLOAT,    },    {        .name = "Fujitsu MB86904",        .iu_version = 0x04 << 24, /* Impl 0, ver 4 */        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */        .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */        .mmu_bm = 0x00004000,        .mmu_ctpr_mask = 0x00ffffc0,

⌨️ 快捷键说明

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