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

📄 helper.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 3 页
字号:
        fprintf(logfile, "Raise exception at 0x%08lx => 0x%08x (%02x)\n",                (unsigned long)env->nip, excp, env->error_code);    }    msr_pow = 0;    /* Generate informations in save/restore registers */    switch (excp) {        /* Generic PowerPC exceptions */    case EXCP_RESET: /* 0x0100 */        if (PPC_EXCP(env) != PPC_FLAGS_EXCP_40x) {            if (msr_ip)                excp += 0xFFC00;            excp |= 0xFFC00000;        } else {            srr_0 = &env->spr[SPR_40x_SRR2];            srr_1 = &env->spr[SPR_40x_SRR3];        }        goto store_next;    case EXCP_MACHINE_CHECK: /* 0x0200 */        if (msr_me == 0) {            cpu_abort(env, "Machine check exception while not allowed\n");        }        if (PPC_EXCP(env) == PPC_FLAGS_EXCP_40x) {            srr_0 = &env->spr[SPR_40x_SRR2];            srr_1 = &env->spr[SPR_40x_SRR3];        }        msr_me = 0;        break;    case EXCP_DSI: /* 0x0300 */        /* Store exception cause */        /* data location address has been stored         * when the fault has been detected         */	msr &= ~0xFFFF0000;#if defined (DEBUG_EXCEPTIONS)	if (loglevel) {	    fprintf(logfile, "DSI exception: DSISR=0x%08x, DAR=0x%08x\n",		    env->spr[SPR_DSISR], env->spr[SPR_DAR]);	} else {	    printf("DSI exception: DSISR=0x%08x, DAR=0x%08x\n",		   env->spr[SPR_DSISR], env->spr[SPR_DAR]);	}#endif        goto store_next;    case EXCP_ISI: /* 0x0400 */        /* Store exception cause */	msr &= ~0xFFFF0000;        msr |= env->error_code;#if defined (DEBUG_EXCEPTIONS)	if (loglevel != 0) {	    fprintf(logfile, "ISI exception: msr=0x%08x, nip=0x%08x\n",		    msr, env->nip);	}#endif        goto store_next;    case EXCP_EXTERNAL: /* 0x0500 */        if (msr_ee == 0) {#if defined (DEBUG_EXCEPTIONS)            if (loglevel > 0) {                fprintf(logfile, "Skipping hardware interrupt\n");            }#endif            /* Requeue it */            env->interrupt_request |= CPU_INTERRUPT_HARD;            return;        }        goto store_next;    case EXCP_ALIGN: /* 0x0600 */        if (PPC_EXCP(env) != PPC_FLAGS_EXCP_601) {            /* Store exception cause */            /* Get rS/rD and rA from faulting opcode */            env->spr[SPR_DSISR] |=                (ldl_code((env->nip - 4)) & 0x03FF0000) >> 16;            /* data location address has been stored             * when the fault has been detected             */        } else {            /* IO error exception on PowerPC 601 */            /* XXX: TODO */            cpu_abort(env,                      "601 IO error exception is not implemented yet !\n");        }        goto store_current;    case EXCP_PROGRAM: /* 0x0700 */        msr &= ~0xFFFF0000;        switch (env->error_code & ~0xF) {        case EXCP_FP:            if (msr_fe0 == 0 && msr_fe1 == 0) {#if defined (DEBUG_EXCEPTIONS)                printf("Ignore floating point exception\n");#endif                return;        }            msr |= 0x00100000;            /* Set FX */            env->fpscr[7] |= 0x8;            /* Finally, update FEX */            if ((((env->fpscr[7] & 0x3) << 3) | (env->fpscr[6] >> 1)) &                ((env->fpscr[1] << 1) | (env->fpscr[0] >> 3)))                env->fpscr[7] |= 0x4;        break;        case EXCP_INVAL:            //	    printf("Invalid instruction at 0x%08x\n", env->nip);            msr |= 0x00080000;        break;        case EXCP_PRIV:            msr |= 0x00040000;        break;        case EXCP_TRAP:            msr |= 0x00020000;            break;        default:            /* Should never occur */        break;    }        msr |= 0x00010000;        goto store_current;    case EXCP_NO_FP: /* 0x0800 */        msr &= ~0xFFFF0000;        goto store_current;    case EXCP_DECR:        if (msr_ee == 0) {#if 1            /* Requeue it */            env->interrupt_request |= CPU_INTERRUPT_TIMER;#endif            return;        }        goto store_next;    case EXCP_SYSCALL: /* 0x0C00 */        /* NOTE: this is a temporary hack to support graphics OSI           calls from the MOL driver */        if (env->gpr[3] == 0x113724fa && env->gpr[4] == 0x77810f9b &&            env->osi_call) {            if (env->osi_call(env) != 0)                return;        }        if (loglevel & CPU_LOG_INT) {            dump_syscall(env);        }        goto store_next;    case EXCP_TRACE: /* 0x0D00 */        /* XXX: TODO */        cpu_abort(env, "Trace exception is not implemented yet !\n");        goto store_next;    case EXCP_PERF: /* 0x0F00 */        /* XXX: TODO */        cpu_abort(env,                  "Performance counter exception is not implemented yet !\n");        goto store_next;    /* 32 bits PowerPC specific exceptions */    case EXCP_FP_ASSIST: /* 0x0E00 */        /* XXX: TODO */        cpu_abort(env, "Floating point assist exception "                  "is not implemented yet !\n");        goto store_next;    /* 64 bits PowerPC exceptions */    case EXCP_DSEG: /* 0x0380 */        /* XXX: TODO */        cpu_abort(env, "Data segment exception is not implemented yet !\n");        goto store_next;    case EXCP_ISEG: /* 0x0480 */        /* XXX: TODO */        cpu_abort(env,                  "Instruction segment exception is not implemented yet !\n");        goto store_next;    case EXCP_HDECR: /* 0x0980 */        if (msr_ee == 0) {#if 1            /* Requeue it */            env->interrupt_request |= CPU_INTERRUPT_TIMER;#endif        return;        }        cpu_abort(env,                  "Hypervisor decrementer exception is not implemented yet !\n");        goto store_next;    /* Implementation specific exceptions */    case 0x0A00:        if (PPC_EXCP(env) != PPC_FLAGS_EXCP_602) {            /* Critical interrupt on G2 */            /* XXX: TODO */            cpu_abort(env, "G2 critical interrupt is not implemented yet !\n");            goto store_next;        } else {            cpu_abort(env, "Invalid exception 0x0A00 !\n");        }        return;    case 0x0F20:        switch (PPC_EXCP(env)) {        case PPC_FLAGS_EXCP_40x:            /* APU unavailable on 405 */            /* XXX: TODO */            cpu_abort(env,                      "APU unavailable exception is not implemented yet !\n");            goto store_next;        case PPC_FLAGS_EXCP_74xx:            /* Altivec unavailable */            /* XXX: TODO */            cpu_abort(env, "Altivec unavailable exception "                      "is not implemented yet !\n");            goto store_next;        default:            cpu_abort(env, "Invalid exception 0x0F20 !\n");            break;        }        return;    case 0x1000:        switch (PPC_EXCP(env)) {        case PPC_FLAGS_EXCP_40x:            /* PIT on 4xx */            /* XXX: TODO */            cpu_abort(env, "40x PIT exception is not implemented yet !\n");            goto store_next;        case PPC_FLAGS_EXCP_602:        case PPC_FLAGS_EXCP_603:            /* ITLBMISS on 602/603 */            msr &= ~0xF00F0000;            msr_tgpr = 1;            goto store_gprs;        default:            cpu_abort(env, "Invalid exception 0x1000 !\n");            break;        }        return;    case 0x1010:        switch (PPC_EXCP(env)) {        case PPC_FLAGS_EXCP_40x:            /* FIT on 4xx */            cpu_abort(env, "40x FIT exception is not implemented yet !\n");            /* XXX: TODO */            goto store_next;        default:            cpu_abort(env, "Invalid exception 0x1010 !\n");            break;        }        return;    case 0x1020:        switch (PPC_EXCP(env)) {        case PPC_FLAGS_EXCP_40x:            /* Watchdog on 4xx */            /* XXX: TODO */            cpu_abort(env,                      "40x watchdog exception is not implemented yet !\n");            goto store_next;        default:            cpu_abort(env, "Invalid exception 0x1020 !\n");            break;        }        return;    case 0x1100:        switch (PPC_EXCP(env)) {        case PPC_FLAGS_EXCP_40x:            /* DTLBMISS on 4xx */            /* XXX: TODO */            cpu_abort(env,                      "40x DTLBMISS exception is not implemented yet !\n");            goto store_next;        case PPC_FLAGS_EXCP_602:        case PPC_FLAGS_EXCP_603:            /* DLTLBMISS on 602/603 */            msr &= ~0xF00F0000;            msr_tgpr = 1;            goto store_gprs;        default:            cpu_abort(env, "Invalid exception 0x1100 !\n");            break;        }        return;    case 0x1200:        switch (PPC_EXCP(env)) {        case PPC_FLAGS_EXCP_40x:            /* ITLBMISS on 4xx */            /* XXX: TODO */            cpu_abort(env,                      "40x ITLBMISS exception is not implemented yet !\n");            goto store_next;        case PPC_FLAGS_EXCP_602:        case PPC_FLAGS_EXCP_603:            /* DSTLBMISS on 602/603 */            msr &= ~0xF00F0000;            msr_tgpr = 1;        store_gprs:#if defined (DEBUG_SOFTWARE_TLB)            if (loglevel != 0) {                fprintf(logfile, "6xx %sTLB miss: IM %08x DM %08x IC %08x "                        "DC %08x H1 %08x H2 %08x %08x\n",                        excp == 0x1000 ? "I" : excp == 0x1100 ? "DL" : "DS",                        env->spr[SPR_IMISS], env->spr[SPR_DMISS],                        env->spr[SPR_ICMP], env->spr[SPR_DCMP],                        env->spr[SPR_DHASH1], env->spr[SPR_DHASH2],                        env->error_code);            }#endif            /* Swap temporary saved registers with GPRs */            tmp = env->gpr[0];            env->gpr[0] = env->tgpr[0];            env->tgpr[0] = tmp;            tmp = env->gpr[1];            env->gpr[1] = env->tgpr[1];            env->tgpr[1] = tmp;            tmp = env->gpr[2];            env->gpr[2] = env->tgpr[2];            env->tgpr[2] = tmp;            tmp = env->gpr[3];            env->gpr[3] = env->tgpr[3];            env->tgpr[3] = tmp;            msr |= env->crf[0] << 28;            msr |= env->error_code; /* key, D/I, S/L bits */            /* Set way using a LRU mechanism */            msr |= (env->last_way ^ 1) << 17;            goto store_next;        default:            cpu_abort(env, "Invalid exception 0x1200 !\n");            break;        }        return;    case 0x1300:        switch (PPC_EXCP(env)) {        case PPC_FLAGS_EXCP_601:        case PPC_FLAGS_EXCP_602:        case PPC_FLAGS_EXCP_603:        case PPC_FLAGS_EXCP_604:        case PPC_FLAGS_EXCP_7x0:        case PPC_FLAGS_EXCP_7x5:            /* IABR on 6xx/7xx */            /* XXX: TODO */            cpu_abort(env, "IABR exception is not implemented yet !\n");            goto store_next;        default:            cpu_abort(env, "Invalid exception 0x1300 !\n");            break;        }        return;    case 0x1400:        switch (PPC_EXCP(env)) {        case PPC_FLAGS_EXCP_601:        case PPC_FLAGS_EXCP_602:        case PPC_FLAGS_EXCP_603:        case PPC_FLAGS_EXCP_604:        case PPC_FLAGS_EXCP_7x0:        case PPC_FLAGS_EXCP_7x5:            /* SMI on 6xx/7xx */            /* XXX: TODO */            cpu_abort(env, "SMI exception is not implemented yet !\n");            goto store_next;        default:            cpu_abort(env, "Invalid exception 0x1400 !\n");            break;        }        return;    case 0x1500:        switch (PPC_EXCP(env)) {        case PPC_FLAGS_EXCP_602:            /* Watchdog on 602 */            cpu_abort(env,                      "602 watchdog exception is not implemented yet !\n");            goto store_next;        case PPC_FLAGS_EXCP_970:            /* Soft patch exception on 970 */            /* XXX: TODO */            cpu_abort(env,                      "970 soft-patch exception is not implemented yet !\n");            goto store_next;        case PPC_FLAGS_EXCP_74xx:            /* VPU assist on 74xx */            /* XXX: TODO */            cpu_abort(env, "VPU assist exception is not implemented yet !\n");            goto store_next;        default:            cpu_abort(env, "Invalid exception 0x1500 !\n");            break;        }        return;    case 0x1600:        switch (PPC_EXCP(env)) {        case PPC_FLAGS_EXCP_602:            /* Emulation trap on 602 */            /* XXX: TODO */            cpu_abort(env, "602 emulation trap exception "                      "is not implemented yet !\n");            goto store_next;        case PPC_FLAGS_EXCP_970:            /* Maintenance exception on 970 */            /* XXX: TODO */            cpu_abort(env,                      "970 maintenance exception is not implemented yet !\n");            goto store_next;        default:            cpu_abort(env, "Invalid exception 0x1600 !\n");            break;        }        return;    case 0x1700:        switch (PPC_EXCP(env)) {        case PPC_FLAGS_EXCP_7x0:        case PPC_FLAGS_EXCP_7x5:            /* Thermal management interrupt on G3 */            /* XXX: TODO */            cpu_abort(env, "G3 thermal management exception "                      "is not implemented yet !\n");            goto store_next;        case PPC_FLAGS_EXCP_970:            /* VPU assist on 970 */            /* XXX: TODO */            cpu_abort(env,                      "970 VPU assist exception is not implemented yet !\n");            goto store_next;        default:            cpu_abort(env, "Invalid exception 0x1700 !\n");            break;        }        return;    case 0x1800:        switch (PPC_EXCP(env)) {        case PPC_FLAGS_EXCP_970:            /* Thermal exception on 970 */            /* XXX: TODO */            cpu_abort(env, "970 thermal management exception "                      "is not implemented yet !\n");            goto store_next;        default:            cpu_abort(env, "Invalid exception 0x1800 !\n");            break;        }        return;    case 0x2000:        switch (PPC_EXCP(env)) {        case PPC_FLAGS_EXCP_40x:            /* DEBUG on 4xx */            /* XXX: TODO */            cpu_abort(env, "40x debug exception is not implemented yet !\n");            goto store_next;        case PPC_FLAGS_EXCP_601:            /* Run mode exception on 601 */            /* XXX: TODO */            cpu_abort(env,                      "601 run mode exception is not implemented yet !\n");            goto store_next;        default:            cpu_abort(env, "Invalid exception 0x1800 !\n");            break;        }        return;    /* Other exceptions */    /* Qemu internal exceptions:     * we should never come here with those values: abort execution     */    default:        cpu_abort(env, "Invalid exception: code %d (%04x)\n", excp, excp);        return;    store_current:        /* save current instruction location */        *srr_0 = (env->nip - 4) & 0xFFFFFFFFULL;        break;    store_next:        /* save next instruction location */        *srr_0 = env->nip & 0xFFFFFFFFULL;        break;    }    /* Save msr */    *srr_1 = msr;    /* If we disactivated any translation, flush TLBs */    if (msr_ir || msr_dr) {        tlb_flush(env, 1);    }    /* reload MSR with correct bits */    msr_ee = 0;    msr_pr = 0;    msr_fp = 0;    msr_fe0 = 0;    msr_se = 0;    msr_be = 0;    msr_fe1 = 0;    msr_ir = 0;    msr_dr = 0;    msr_ri = 0;    msr_le = msr_ile;    msr_sf = msr_isf;    do_compute_hflags(env);    /* Jump to handler */    env->nip = excp;    env->exception_index = EXCP_NONE;}#endif /* !CONFIG_USER_ONLY */

⌨️ 快捷键说明

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