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 + -
显示快捷键?