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

📄 helper.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include "cpu.h"#include "exec-all.h"void cpu_reset(CPUARMState *env){#if defined (CONFIG_USER_ONLY)    env->uncached_cpsr = ARM_CPU_MODE_USR;    env->vfp.xregs[ARM_VFP_FPEXC] = 1 << 30;#else    /* SVC mode with interrupts disabled.  */    env->uncached_cpsr = ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I;    env->vfp.xregs[ARM_VFP_FPEXC] = 0;#endif    env->regs[15] = 0;}CPUARMState *cpu_arm_init(void){    CPUARMState *env;    env = qemu_mallocz(sizeof(CPUARMState));    if (!env)        return NULL;    cpu_exec_init(env);    cpu_reset(env);    tlb_flush(env, 1);    return env;}static inline void set_feature(CPUARMState *env, int feature){    env->features |= 1u << feature;}void cpu_arm_set_model(CPUARMState *env, uint32_t id){    env->cp15.c0_cpuid = id;    switch (id) {    case ARM_CPUID_ARM926:        set_feature(env, ARM_FEATURE_VFP);        env->vfp.xregs[ARM_VFP_FPSID] = 0x41011090;        break;    case ARM_CPUID_ARM1026:        set_feature(env, ARM_FEATURE_VFP);        set_feature(env, ARM_FEATURE_AUXCR);        env->vfp.xregs[ARM_VFP_FPSID] = 0x410110a0;        break;    default:        cpu_abort(env, "Bad CPU ID: %x\n", id);        break;    }}void cpu_arm_close(CPUARMState *env){    free(env);}#if defined(CONFIG_USER_ONLY) void do_interrupt (CPUState *env){    env->exception_index = -1;}int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, int rw,                              int is_user, int is_softmmu){    if (rw == 2) {        env->exception_index = EXCP_PREFETCH_ABORT;        env->cp15.c6_insn = address;    } else {        env->exception_index = EXCP_DATA_ABORT;        env->cp15.c6_data = address;    }    return 1;}target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr){    return addr;}/* These should probably raise undefined insn exceptions.  */void helper_set_cp15(CPUState *env, uint32_t insn, uint32_t val){    cpu_abort(env, "cp15 insn %08x\n", insn);}uint32_t helper_get_cp15(CPUState *env, uint32_t insn){    cpu_abort(env, "cp15 insn %08x\n", insn);    return 0;}void switch_mode(CPUState *env, int mode){    if (mode != ARM_CPU_MODE_USR)        cpu_abort(env, "Tried to switch out of user mode\n");}#else/* Map CPU modes onto saved register banks.  */static inline int bank_number (int mode){    switch (mode) {    case ARM_CPU_MODE_USR:    case ARM_CPU_MODE_SYS:        return 0;    case ARM_CPU_MODE_SVC:        return 1;    case ARM_CPU_MODE_ABT:        return 2;    case ARM_CPU_MODE_UND:        return 3;    case ARM_CPU_MODE_IRQ:        return 4;    case ARM_CPU_MODE_FIQ:        return 5;    }    cpu_abort(cpu_single_env, "Bad mode %x\n", mode);    return -1;}void switch_mode(CPUState *env, int mode){    int old_mode;    int i;    old_mode = env->uncached_cpsr & CPSR_M;    if (mode == old_mode)        return;    if (old_mode == ARM_CPU_MODE_FIQ) {        memcpy (env->fiq_regs, env->regs + 8, 5 * sizeof(uint32_t));        memcpy (env->regs + 8, env->usr_regs, 5 * sizeof(uint32_t));    } else if (mode == ARM_CPU_MODE_FIQ) {        memcpy (env->usr_regs, env->regs + 8, 5 * sizeof(uint32_t));        memcpy (env->regs + 8, env->fiq_regs, 5 * sizeof(uint32_t));    }    i = bank_number(old_mode);    env->banked_r13[i] = env->regs[13];    env->banked_r14[i] = env->regs[14];    env->banked_spsr[i] = env->spsr;    i = bank_number(mode);    env->regs[13] = env->banked_r13[i];    env->regs[14] = env->banked_r14[i];    env->spsr = env->banked_spsr[i];}/* Handle a CPU exception.  */void do_interrupt(CPUARMState *env){    uint32_t addr;    uint32_t mask;    int new_mode;    uint32_t offset;    /* TODO: Vectored interrupt controller.  */    switch (env->exception_index) {    case EXCP_UDEF:        new_mode = ARM_CPU_MODE_UND;        addr = 0x04;        mask = CPSR_I;        if (env->thumb)            offset = 2;        else            offset = 4;        break;    case EXCP_SWI:        new_mode = ARM_CPU_MODE_SVC;        addr = 0x08;        mask = CPSR_I;        /* The PC already points to the next instructon.  */        offset = 0;        break;    case EXCP_PREFETCH_ABORT:    case EXCP_BKPT:        new_mode = ARM_CPU_MODE_ABT;        addr = 0x0c;        mask = CPSR_A | CPSR_I;        offset = 4;        break;    case EXCP_DATA_ABORT:        new_mode = ARM_CPU_MODE_ABT;        addr = 0x10;        mask = CPSR_A | CPSR_I;        offset = 8;        break;    case EXCP_IRQ:        new_mode = ARM_CPU_MODE_IRQ;        addr = 0x18;        /* Disable IRQ and imprecise data aborts.  */        mask = CPSR_A | CPSR_I;        offset = 4;        break;    case EXCP_FIQ:        new_mode = ARM_CPU_MODE_FIQ;        addr = 0x1c;        /* Disable FIQ, IRQ and imprecise data aborts.  */        mask = CPSR_A | CPSR_I | CPSR_F;        offset = 4;        break;    default:        cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);        return; /* Never happens.  Keep compiler happy.  */    }    /* High vectors.  */    if (env->cp15.c1_sys & (1 << 13)) {        addr += 0xffff0000;    }    switch_mode (env, new_mode);    env->spsr = cpsr_read(env);    /* Switch to the new mode, and switch to Arm mode.  */    /* ??? Thumb interrupt handlers not implemented.  */    env->uncached_cpsr = (env->uncached_cpsr & ~CPSR_M) | new_mode;    env->uncached_cpsr |= mask;    env->thumb = 0;    env->regs[14] = env->regs[15] + offset;    env->regs[15] = addr;    env->interrupt_request |= CPU_INTERRUPT_EXITTB;}/* Check section/page access permissions.   Returns the page protection flags, or zero if the access is not   permitted.  */static inline int check_ap(CPUState *env, int ap, int domain, int access_type,                           int is_user){  if (domain == 3)    return PAGE_READ | PAGE_WRITE;  switch (ap) {  case 0:      if (access_type != 1)          return 0;      switch ((env->cp15.c1_sys >> 8) & 3) {      case 1:          return is_user ? 0 : PAGE_READ;      case 2:          return PAGE_READ;      default:          return 0;      }  case 1:      return is_user ? 0 : PAGE_READ | PAGE_WRITE;  case 2:      if (is_user)          return (access_type == 1) ? 0 : PAGE_READ;      else          return PAGE_READ | PAGE_WRITE;  case 3:      return PAGE_READ | PAGE_WRITE;  default:      abort();  }}static int get_phys_addr(CPUState *env, uint32_t address, int access_type,                         int is_user, uint32_t *phys_ptr, int *prot){    int code;    uint32_t table;    uint32_t desc;    int type;    int ap;    int domain;    uint32_t phys_addr;    /* Fast Context Switch Extension.  */    if (address < 0x02000000)        address += env->cp15.c13_fcse;    if ((env->cp15.c1_sys & 1) == 0) {        /* MMU diusabled.  */        *phys_ptr = address;        *prot = PAGE_READ | PAGE_WRITE;    } else {        /* Pagetable walk.  */        /* Lookup l1 descriptor.  */        table = (env->cp15.c2 & 0xffffc000) | ((address >> 18) & 0x3ffc);        desc = ldl_phys(table);        type = (desc & 3);        domain = (env->cp15.c3 >> ((desc >> 4) & 0x1e)) & 3;        if (type == 0) {            /* Secton translation fault.  */            code = 5;            goto do_fault;        }        if (domain == 0 || domain == 2) {            if (type == 2)                code = 9; /* Section domain fault.  */            else                code = 11; /* Page domain fault.  */            goto do_fault;        }        if (type == 2) {            /* 1Mb section.  */            phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);            ap = (desc >> 10) & 3;            code = 13;        } else {

⌨️ 快捷键说明

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