qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 3/6] Added Aarch64 CPU Initialization, Get and P


From: Alexander Graf
Subject: Re: [Qemu-devel] [PATCH 3/6] Added Aarch64 CPU Initialization, Get and Put Registers Support.
Date: Fri, 28 Jun 2013 14:43:10 +0200

On 28.06.2013, at 14:11, Mian M. Hamayun wrote:

> From: "Mian M. Hamayun" <address@hidden>
> 
> The init function tries to initialize with Foundation models first and on
> failure retries initializing on Fast Models.
> 
> Get and Put Registers deal with the basic state of Aarch64 CPUs for the 
> moment.
> 
> Signed-off-by: Mian M. Hamayun <address@hidden>
> ---
> linux-headers/linux/kvm.h |    1 +
> target-arm/cpu.c          |    8 +++
> target-arm/cpu.h          |    1 +
> target-arm/kvm.c          |  120 +++++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 130 insertions(+)
> 
> diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
> index c614070..4df5292 100644
> --- a/linux-headers/linux/kvm.h
> +++ b/linux-headers/linux/kvm.h
> @@ -783,6 +783,7 @@ struct kvm_dirty_tlb {
> #define KVM_REG_IA64          0x3000000000000000ULL
> #define KVM_REG_ARM           0x4000000000000000ULL
> #define KVM_REG_S390          0x5000000000000000ULL
> +#define KVM_REG_ARM64          0x6000000000000000ULL
> 
> #define KVM_REG_SIZE_SHIFT    52
> #define KVM_REG_SIZE_MASK     0x00f0000000000000ULL

This should be part of your header update patch.

> diff --git a/target-arm/cpu.c b/target-arm/cpu.c
> index 496a59f..34eba77 100644
> --- a/target-arm/cpu.c
> +++ b/target-arm/cpu.c
> @@ -601,6 +601,13 @@ static void cortex_a15_initfn(Object *obj)
>     define_arm_cp_regs(cpu, cortexa15_cp_reginfo);
> }
> 
> +static void cortex_a57_initfn(Object *obj)
> +{
> +    ARMCPU *cpu = ARM_CPU(obj);
> +    set_feature(&cpu->env, ARM_FEATURE_V8);
> +    cpu->env.aarch64 = 1;      /* We force 64-bit mode for guests */
> +}
> +
> static void ti925t_initfn(Object *obj)
> {
>     ARMCPU *cpu = ARM_CPU(obj);
> @@ -781,6 +788,7 @@ static const ARMCPUInfo arm_cpus[] = {
>     { .name = "cortex-a8",   .initfn = cortex_a8_initfn },
>     { .name = "cortex-a9",   .initfn = cortex_a9_initfn },
>     { .name = "cortex-a15",  .initfn = cortex_a15_initfn },
> +    { .name = "cortex-a57",  .initfn = cortex_a57_initfn },
>     { .name = "ti925t",      .initfn = ti925t_initfn },
>     { .name = "sa1100",      .initfn = sa1100_initfn },
>     { .name = "sa1110",      .initfn = sa1110_initfn },
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index cd42814..f1cae7f 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -410,6 +410,7 @@ enum arm_features {
>     ARM_FEATURE_V6,
>     ARM_FEATURE_V6K,
>     ARM_FEATURE_V7,
> +    ARM_FEATURE_V8,
>     ARM_FEATURE_THUMB2,
>     ARM_FEATURE_MPU,    /* Only has Memory Protection Unit, not full MMU.  */
>     ARM_FEATURE_VFP3,
> diff --git a/target-arm/kvm.c b/target-arm/kvm.c
> index 27dcab9..0125f16 100644
> --- a/target-arm/kvm.c
> +++ b/target-arm/kvm.c
> @@ -23,6 +23,11 @@
> #include "cpu.h"
> #include "hw/arm/arm.h"
> 
> +#ifdef TARGET_AARCH64
> +#define AARCH64_CORE_REG(x)   (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
> +                 KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x))
> +#endif
> +
> const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
>     KVM_CAP_LAST_INFO
> };
> @@ -41,6 +46,28 @@ unsigned long kvm_arch_vcpu_id(CPUState *cpu)
>     return cpu->cpu_index;
> }
> 
> +#ifdef TARGET_AARCH64
> +int kvm_arch_init_vcpu(CPUState *cs)
> +{
> +    struct kvm_vcpu_init init;
> +    int ret;
> +
> +    /* Try initializing with Foundation Models */
> +    init.target = KVM_ARM_TARGET_FOUNDATION_V8;
> +    memset(init.features, 0, sizeof(init.features));
> +    ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init);
> +    if (ret) {
> +        /* Retry initializing with Fast Models */
> +        init.target = KVM_ARM_TARGET_AEM_V8;
> +        ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init);

Not sure I understand this part. Do we have different CPU types for the 
different models? If so, they'd be different -cpu parameters, with -cpu host 
picking the same as the host's.

> +        if (ret) {
> +            return ret;
> +        }
> +    }
> +
> +    return ret;
> +}
> +#else
> int kvm_arch_init_vcpu(CPUState *cs)
> {
>     struct kvm_vcpu_init init;
> @@ -67,6 +94,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
>     }
>     return ret;
> }
> +#endif
> 
> /* We track all the KVM devices which need their memory addresses
>  * passing to the kernel in a list of these structures.
> @@ -159,6 +187,7 @@ typedef struct Reg {
>     int offset;
> } Reg;
> 
> +#ifndef TARGET_AARCH64
> #define COREREG(KERNELNAME, QEMUFIELD)                       \
>     {                                                        \
>         KVM_REG_ARM | KVM_REG_SIZE_U32 |                     \
> @@ -239,7 +268,52 @@ static const Reg regs[] = {
>     VFPSYSREG(FPINST),
>     VFPSYSREG(FPINST2),
> };
> +#endif
> +
> +#ifdef TARGET_AARCH64
> +int kvm_arch_put_registers(CPUState *cs, int level)

How does the register transaction interface look like for aarch64 kvm? Are 
aarch32 registers mapped onto aarch64 ones or are they a separate set of 
registers? If they're a separate set, just add the aarch64 register sync to the 
aarch32 one.

> +{
> +    struct kvm_one_reg reg;
> +    int i;
> +    int ret;
> +
> +    ARMCPU *cpu = ARM_CPU(cs);
> +    CPUARMState *env = &cpu->env;
> +
> +    for (i = 0; i < 31; i++) {

s/31/ARRAY_SIZE(...)/

> +        reg.id = AARCH64_CORE_REG(regs.regs[i]);
> +        reg.addr = (uintptr_t)(env) + offsetof(CPUARMState, xregs[i]);

reg.addr = (uintptr_t)&env->xregs[i];

Same below.


Alex

> +        ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
> +        if (ret) {
> +            return ret;
> +        }
> +    }
> +
> +    reg.id = AARCH64_CORE_REG(regs.sp);
> +    reg.addr = (uintptr_t)(env) + offsetof(CPUARMState, xregs[31]);
> +    ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
> +    if (ret) {
> +        return ret;
> +    }
> +
> +    reg.id = AARCH64_CORE_REG(regs.pstate);
> +    reg.addr = (uintptr_t)(env) + offsetof(CPUARMState, pstate);
> +    ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
> +    if (ret) {
> +        return ret;
> +    }
> 
> +    reg.id = AARCH64_CORE_REG(regs.pc);
> +    reg.addr = (uintptr_t)(env) + offsetof(CPUARMState, pc);
> +    ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
> +    if (ret) {
> +        return ret;
> +    }
> +
> +    /* TODO: Set Rest of Registers */
> +    return ret;
> +}
> +#else
> int kvm_arch_put_registers(CPUState *cs, int level)
> {
>     ARMCPU *cpu = ARM_CPU(cs);
> @@ -321,7 +395,52 @@ int kvm_arch_put_registers(CPUState *cs, int level)
> 
>     return ret;
> }
> +#endif
> +
> +#ifdef TARGET_AARCH64
> +int kvm_arch_get_registers(CPUState *cs)
> +{
> +    struct kvm_one_reg reg;
> +    int i;
> +    int ret;
> +
> +    ARMCPU *cpu = ARM_CPU(cs);
> +    CPUARMState *env = &cpu->env;
> +
> +    for (i = 0; i < 31; i++) {
> +        reg.id = AARCH64_CORE_REG(regs.regs[i]);
> +        reg.addr = (uintptr_t)(env) + offsetof(CPUARMState, xregs[i]);
> +        ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
> +        if (ret) {
> +            return ret;
> +        }
> +    }
> 
> +    reg.id = AARCH64_CORE_REG(regs.sp);
> +    reg.addr = (uintptr_t)(env) + offsetof(CPUARMState, xregs[31]);
> +    ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
> +    if (ret) {
> +        return ret;
> +    }
> +
> +    reg.id = AARCH64_CORE_REG(regs.pstate);
> +    reg.addr = (uintptr_t)(env) + offsetof(CPUARMState, pstate);
> +    ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
> +    if (ret) {
> +        return ret;
> +    }
> +
> +    reg.id = AARCH64_CORE_REG(regs.pc);
> +    reg.addr = (uintptr_t)(env) + offsetof(CPUARMState, pc);
> +    ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
> +    if (ret) {
> +        return ret;
> +    }
> +
> +    /* TODO: Set Rest of Registers */
> +    return ret;
> +}
> +#else
> int kvm_arch_get_registers(CPUState *cs)
> {
>     ARMCPU *cpu = ARM_CPU(cs);
> @@ -416,6 +535,7 @@ int kvm_arch_get_registers(CPUState *cs)
> 
>     return 0;
> }
> +#endif
> 
> void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)
> {
> -- 
> 1.7.9.5
> 
> _______________________________________________
> kvmarm mailing list
> address@hidden
> https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm




reply via email to

[Prev in Thread] Current Thread [Next in Thread]