Annotation of qemu/target-ppc/kvm.c, revision 1.1.1.2

1.1       root        1: /*
                      2:  * PowerPC implementation of KVM hooks
                      3:  *
                      4:  * Copyright IBM Corp. 2007
                      5:  *
                      6:  * Authors:
                      7:  *  Jerone Young <[email protected]>
                      8:  *  Christian Ehrhardt <[email protected]>
                      9:  *  Hollis Blanchard <[email protected]>
                     10:  *
                     11:  * This work is licensed under the terms of the GNU GPL, version 2 or later.
                     12:  * See the COPYING file in the top-level directory.
                     13:  *
                     14:  */
                     15: 
                     16: #include <sys/types.h>
                     17: #include <sys/ioctl.h>
                     18: #include <sys/mman.h>
                     19: 
                     20: #include <linux/kvm.h>
                     21: 
                     22: #include "qemu-common.h"
                     23: #include "qemu-timer.h"
                     24: #include "sysemu.h"
                     25: #include "kvm.h"
                     26: #include "kvm_ppc.h"
                     27: #include "cpu.h"
                     28: #include "device_tree.h"
                     29: 
                     30: //#define DEBUG_KVM
                     31: 
                     32: #ifdef DEBUG_KVM
                     33: #define dprintf(fmt, ...) \
                     34:     do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
                     35: #else
                     36: #define dprintf(fmt, ...) \
                     37:     do { } while (0)
                     38: #endif
                     39: 
                     40: int kvm_arch_init(KVMState *s, int smp_cpus)
                     41: {
                     42:     return 0;
                     43: }
                     44: 
                     45: int kvm_arch_init_vcpu(CPUState *cenv)
                     46: {
1.1.1.2 ! root       47:     int ret = 0;
        !            48:     struct kvm_sregs sregs;
        !            49: 
        !            50:     sregs.pvr = cenv->spr[SPR_PVR];
        !            51:     ret = kvm_vcpu_ioctl(cenv, KVM_SET_SREGS, &sregs);
        !            52: 
        !            53:     return ret;
        !            54: }
        !            55: 
        !            56: void kvm_arch_reset_vcpu(CPUState *env)
        !            57: {
1.1       root       58: }
                     59: 
                     60: int kvm_arch_put_registers(CPUState *env)
                     61: {
                     62:     struct kvm_regs regs;
                     63:     int ret;
                     64:     int i;
                     65: 
                     66:     ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, &regs);
                     67:     if (ret < 0)
                     68:         return ret;
                     69: 
                     70:     regs.ctr = env->ctr;
                     71:     regs.lr  = env->lr;
                     72:     regs.xer = env->xer;
                     73:     regs.msr = env->msr;
                     74:     regs.pc = env->nip;
                     75: 
                     76:     regs.srr0 = env->spr[SPR_SRR0];
                     77:     regs.srr1 = env->spr[SPR_SRR1];
                     78: 
                     79:     regs.sprg0 = env->spr[SPR_SPRG0];
                     80:     regs.sprg1 = env->spr[SPR_SPRG1];
                     81:     regs.sprg2 = env->spr[SPR_SPRG2];
                     82:     regs.sprg3 = env->spr[SPR_SPRG3];
                     83:     regs.sprg4 = env->spr[SPR_SPRG4];
                     84:     regs.sprg5 = env->spr[SPR_SPRG5];
                     85:     regs.sprg6 = env->spr[SPR_SPRG6];
                     86:     regs.sprg7 = env->spr[SPR_SPRG7];
                     87: 
                     88:     for (i = 0;i < 32; i++)
                     89:         regs.gpr[i] = env->gpr[i];
                     90: 
                     91:     ret = kvm_vcpu_ioctl(env, KVM_SET_REGS, &regs);
                     92:     if (ret < 0)
                     93:         return ret;
                     94: 
                     95:     return ret;
                     96: }
                     97: 
                     98: int kvm_arch_get_registers(CPUState *env)
                     99: {
                    100:     struct kvm_regs regs;
1.1.1.2 ! root      101:     struct kvm_sregs sregs;
1.1       root      102:     uint32_t i, ret;
                    103: 
                    104:     ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, &regs);
                    105:     if (ret < 0)
                    106:         return ret;
                    107: 
1.1.1.2 ! root      108:     ret = kvm_vcpu_ioctl(env, KVM_GET_SREGS, &sregs);
        !           109:     if (ret < 0)
        !           110:         return ret;
        !           111: 
1.1       root      112:     env->ctr = regs.ctr;
                    113:     env->lr = regs.lr;
                    114:     env->xer = regs.xer;
                    115:     env->msr = regs.msr;
                    116:     env->nip = regs.pc;
                    117: 
                    118:     env->spr[SPR_SRR0] = regs.srr0;
                    119:     env->spr[SPR_SRR1] = regs.srr1;
                    120: 
                    121:     env->spr[SPR_SPRG0] = regs.sprg0;
                    122:     env->spr[SPR_SPRG1] = regs.sprg1;
                    123:     env->spr[SPR_SPRG2] = regs.sprg2;
                    124:     env->spr[SPR_SPRG3] = regs.sprg3;
                    125:     env->spr[SPR_SPRG4] = regs.sprg4;
                    126:     env->spr[SPR_SPRG5] = regs.sprg5;
                    127:     env->spr[SPR_SPRG6] = regs.sprg6;
                    128:     env->spr[SPR_SPRG7] = regs.sprg7;
                    129: 
                    130:     for (i = 0;i < 32; i++)
                    131:         env->gpr[i] = regs.gpr[i];
                    132: 
1.1.1.2 ! root      133: #ifdef KVM_CAP_PPC_SEGSTATE
        !           134:     if (kvm_check_extension(env->kvm_state, KVM_CAP_PPC_SEGSTATE)) {
        !           135:         env->sdr1 = sregs.u.s.sdr1;
        !           136: 
        !           137:         /* Sync SLB */
        !           138: #ifdef TARGET_PPC64
        !           139:         for (i = 0; i < 64; i++) {
        !           140:             ppc_store_slb(env, sregs.u.s.ppc64.slb[i].slbe,
        !           141:                                sregs.u.s.ppc64.slb[i].slbv);
        !           142:         }
        !           143: #endif
        !           144: 
        !           145:         /* Sync SRs */
        !           146:         for (i = 0; i < 16; i++) {
        !           147:             env->sr[i] = sregs.u.s.ppc32.sr[i];
        !           148:         }
        !           149: 
        !           150:         /* Sync BATs */
        !           151:         for (i = 0; i < 8; i++) {
        !           152:             env->DBAT[0][i] = sregs.u.s.ppc32.dbat[i] & 0xffffffff;
        !           153:             env->DBAT[1][i] = sregs.u.s.ppc32.dbat[i] >> 32;
        !           154:             env->IBAT[0][i] = sregs.u.s.ppc32.ibat[i] & 0xffffffff;
        !           155:             env->IBAT[1][i] = sregs.u.s.ppc32.ibat[i] >> 32;
        !           156:         }
        !           157:     }
        !           158: #endif
        !           159: 
1.1       root      160:     return 0;
                    161: }
                    162: 
1.1.1.2 ! root      163: #if defined(TARGET_PPCEMB)
        !           164: #define PPC_INPUT_INT PPC40x_INPUT_INT
        !           165: #elif defined(TARGET_PPC64)
        !           166: #define PPC_INPUT_INT PPC970_INPUT_INT
        !           167: #else
        !           168: #define PPC_INPUT_INT PPC6xx_INPUT_INT
        !           169: #endif
        !           170: 
1.1       root      171: int kvm_arch_pre_run(CPUState *env, struct kvm_run *run)
                    172: {
                    173:     int r;
                    174:     unsigned irq;
                    175: 
                    176:     /* PowerPC Qemu tracks the various core input pins (interrupt, critical
                    177:      * interrupt, reset, etc) in PPC-specific env->irq_input_state. */
                    178:     if (run->ready_for_interrupt_injection &&
                    179:         (env->interrupt_request & CPU_INTERRUPT_HARD) &&
1.1.1.2 ! root      180:         (env->irq_input_state & (1<<PPC_INPUT_INT)))
1.1       root      181:     {
                    182:         /* For now KVM disregards the 'irq' argument. However, in the
                    183:          * future KVM could cache it in-kernel to avoid a heavyweight exit
                    184:          * when reading the UIC.
                    185:          */
                    186:         irq = -1U;
                    187: 
                    188:         dprintf("injected interrupt %d\n", irq);
                    189:         r = kvm_vcpu_ioctl(env, KVM_INTERRUPT, &irq);
                    190:         if (r < 0)
                    191:             printf("cpu %d fail inject %x\n", env->cpu_index, irq);
                    192:     }
                    193: 
                    194:     /* We don't know if there are more interrupts pending after this. However,
                    195:      * the guest will return to userspace in the course of handling this one
                    196:      * anyways, so we will get a chance to deliver the rest. */
                    197:     return 0;
                    198: }
                    199: 
                    200: int kvm_arch_post_run(CPUState *env, struct kvm_run *run)
                    201: {
                    202:     return 0;
                    203: }
                    204: 
                    205: static int kvmppc_handle_halt(CPUState *env)
                    206: {
                    207:     if (!(env->interrupt_request & CPU_INTERRUPT_HARD) && (msr_ee)) {
                    208:         env->halted = 1;
                    209:         env->exception_index = EXCP_HLT;
                    210:     }
                    211: 
                    212:     return 1;
                    213: }
                    214: 
                    215: /* map dcr access to existing qemu dcr emulation */
                    216: static int kvmppc_handle_dcr_read(CPUState *env, uint32_t dcrn, uint32_t *data)
                    217: {
                    218:     if (ppc_dcr_read(env->dcr_env, dcrn, data) < 0)
                    219:         fprintf(stderr, "Read to unhandled DCR (0x%x)\n", dcrn);
                    220: 
                    221:     return 1;
                    222: }
                    223: 
                    224: static int kvmppc_handle_dcr_write(CPUState *env, uint32_t dcrn, uint32_t data)
                    225: {
                    226:     if (ppc_dcr_write(env->dcr_env, dcrn, data) < 0)
                    227:         fprintf(stderr, "Write to unhandled DCR (0x%x)\n", dcrn);
                    228: 
                    229:     return 1;
                    230: }
                    231: 
                    232: int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run)
                    233: {
                    234:     int ret = 0;
                    235: 
                    236:     switch (run->exit_reason) {
                    237:     case KVM_EXIT_DCR:
                    238:         if (run->dcr.is_write) {
                    239:             dprintf("handle dcr write\n");
                    240:             ret = kvmppc_handle_dcr_write(env, run->dcr.dcrn, run->dcr.data);
                    241:         } else {
                    242:             dprintf("handle dcr read\n");
                    243:             ret = kvmppc_handle_dcr_read(env, run->dcr.dcrn, &run->dcr.data);
                    244:         }
                    245:         break;
                    246:     case KVM_EXIT_HLT:
                    247:         dprintf("handle halt\n");
                    248:         ret = kvmppc_handle_halt(env);
                    249:         break;
                    250:     }
                    251: 
                    252:     return ret;
                    253: }
                    254: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.