All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 0/6] ARM: add PSCI emulation support
@ 2014-05-23  2:30 Rob Herring
  2014-05-23  2:30 ` [Qemu-devel] [PATCH v2 1/6] target-arm: don't set cpu do_interrupt handler for user mode emulation Rob Herring
                   ` (5 more replies)
  0 siblings, 6 replies; 17+ messages in thread
From: Rob Herring @ 2014-05-23  2:30 UTC (permalink / raw
  To: Peter Maydell
  Cc: Rob Herring, Peter Crosthwaite, qemu-devel, Christoffer Dall

From: Rob Herring <rob.herring@linaro.org>

This series adds support for emulating ARM PSCI calls. PSCI or Power
State Coordination Interface is an ARM standard for controlling cpu
power states. This series supports both AArch32 and AArch64 using HVC or
SMC calls.

This is based on version 6 of Pranavkumar Sawargaonkar's series for PSCI 
0.2 support in KVM[1].

Rob

[1] http://lists.gnu.org/archive/html/qemu-devel/2014-05/msg04514.html

Rob Herring (6):
  target-arm: don't set cpu do_interrupt handler for user mode emulation
  target-arm: add powered off cpu state
  target-arm: add hvc and smc exception emulation handling
    infrastructure
  target-arm: add emulation of PSCI calls for system emulation
  arm/virt: enable PSCI emulation support for system emulation
  arm/highbank: enable PSCI emulation support

 hw/arm/highbank.c          |   9 +++
 hw/arm/virt.c              |  41 +++++-------
 target-arm/Makefile.objs   |   2 +-
 target-arm/cpu-qom.h       |  11 ++++
 target-arm/cpu.c           |  10 ++-
 target-arm/cpu.h           |   2 +
 target-arm/cpu64.c         |   2 +
 target-arm/helper-a64.c    |  35 ++++++++--
 target-arm/helper.c        |  53 +++++++++++++--
 target-arm/internals.h     |  20 ++++++
 target-arm/kvm-consts.h    |   6 ++
 target-arm/machine.c       |   5 +-
 target-arm/psci.c          | 157 +++++++++++++++++++++++++++++++++++++++++++++
 target-arm/translate-a64.c |  13 +++-
 target-arm/translate.c     |  24 +++++--
 15 files changed, 340 insertions(+), 50 deletions(-)
 create mode 100644 target-arm/psci.c

-- 
1.9.1

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH v2 1/6] target-arm: don't set cpu do_interrupt handler for user mode emulation
  2014-05-23  2:30 [Qemu-devel] [PATCH v2 0/6] ARM: add PSCI emulation support Rob Herring
@ 2014-05-23  2:30 ` Rob Herring
  2014-06-03 15:02   ` Peter Maydell
  2014-05-23  2:30 ` [Qemu-devel] [PATCH v2 2/6] target-arm: add powered off cpu state Rob Herring
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 17+ messages in thread
From: Rob Herring @ 2014-05-23  2:30 UTC (permalink / raw
  To: Peter Maydell
  Cc: Rob Herring, Peter Crosthwaite, qemu-devel, Christoffer Dall

From: Rob Herring <rob.herring@linaro.org>

In preparation to add system mode only calls to
aarch64_cpu_do_interrupt, compile it for system mode only and don't set
the do_interrupt callback for user mode emulation. User mode emulation
should never get interrupts and thus should not have a exception handler
function. Do the same change from AArch32 to keep them aligned.

Signed-off-by: Rob Herring <rob.herring@linaro.org>
---
v2:
- Only set .do_interrupt function for system emulation on A32 and A64.

 target-arm/cpu.c        | 2 +-
 target-arm/cpu64.c      | 2 ++
 target-arm/helper-a64.c | 3 +++
 target-arm/helper.c     | 5 -----
 4 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 589f34d..f46b375 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -1038,7 +1038,6 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)

     cc->class_by_name = arm_cpu_class_by_name;
     cc->has_work = arm_cpu_has_work;
-    cc->do_interrupt = arm_cpu_do_interrupt;
     cc->dump_state = arm_cpu_dump_state;
     cc->set_pc = arm_cpu_set_pc;
     cc->gdb_read_register = arm_cpu_gdb_read_register;
@@ -1046,6 +1045,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
 #ifdef CONFIG_USER_ONLY
     cc->handle_mmu_fault = arm_cpu_handle_mmu_fault;
 #else
+    cc->do_interrupt = arm_cpu_do_interrupt;
     cc->get_phys_page_debug = arm_cpu_get_phys_page_debug;
     cc->vmsd = &vmstate_arm_cpu;
 #endif
diff --git a/target-arm/cpu64.c b/target-arm/cpu64.c
index 8daa622..b155579 100644
--- a/target-arm/cpu64.c
+++ b/target-arm/cpu64.c
@@ -187,7 +187,9 @@ static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
 {
     CPUClass *cc = CPU_CLASS(oc);

+#if !defined(CONFIG_USER_ONLY)
     cc->do_interrupt = aarch64_cpu_do_interrupt;
+#endif
     cc->set_pc = aarch64_cpu_set_pc;
     cc->gdb_read_register = aarch64_cpu_gdb_read_register;
     cc->gdb_write_register = aarch64_cpu_gdb_write_register;
diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
index bf921cc..84411b4 100644
--- a/target-arm/helper-a64.c
+++ b/target-arm/helper-a64.c
@@ -438,6 +438,8 @@ float32 HELPER(fcvtx_f64_to_f32)(float64 a, CPUARMState *env)
     return r;
 }

+#if !defined(CONFIG_USER_ONLY)
+
 /* Handle a CPU exception.  */
 void aarch64_cpu_do_interrupt(CPUState *cs)
 {
@@ -512,3 +514,4 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
     env->pc = addr;
     cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
 }
+#endif
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 417161e..1307473 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3004,11 +3004,6 @@ uint32_t HELPER(rbit)(uint32_t x)

 #if defined(CONFIG_USER_ONLY)

-void arm_cpu_do_interrupt(CPUState *cs)
-{
-    cs->exception_index = -1;
-}
-
 int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
                              int mmu_idx)
 {
--
1.9.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH v2 2/6] target-arm: add powered off cpu state
  2014-05-23  2:30 [Qemu-devel] [PATCH v2 0/6] ARM: add PSCI emulation support Rob Herring
  2014-05-23  2:30 ` [Qemu-devel] [PATCH v2 1/6] target-arm: don't set cpu do_interrupt handler for user mode emulation Rob Herring
@ 2014-05-23  2:30 ` Rob Herring
  2014-06-03 14:45   ` Peter Maydell
  2014-05-23  2:30 ` [Qemu-devel] [PATCH v2 3/6] target-arm: add hvc and smc exception emulation handling infrastructure Rob Herring
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 17+ messages in thread
From: Rob Herring @ 2014-05-23  2:30 UTC (permalink / raw
  To: Peter Maydell
  Cc: Rob Herring, Peter Crosthwaite, qemu-devel, Christoffer Dall

From: Rob Herring <rob.herring@linaro.org>

Add tracking of cpu power state in order to support powering off of
cores in system emulation. The initial state is determined by the
start-powered-off QOM property.

Signed-off-by: Rob Herring <rob.herring@linaro.org>
---
v2:
- Add vmstate for powered_off

 target-arm/cpu-qom.h | 2 ++
 target-arm/cpu.c     | 7 ++++++-
 target-arm/machine.c | 5 +++--
 3 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index eaee944..f835900 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -102,6 +102,8 @@ typedef struct ARMCPU {

     /* Should CPU start in PSCI powered-off state? */
     bool start_powered_off;
+    /* CPU currently in PSCI powered-off state */
+    bool powered_off;

     /* [QEMU_]KVM_ARM_TARGET_* constant for this CPU, or
      * QEMU_KVM_ARM_TARGET_NONE if the kernel doesn't support this CPU type.
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index f46b375..a0f9916 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -40,7 +40,9 @@ static void arm_cpu_set_pc(CPUState *cs, vaddr value)

 static bool arm_cpu_has_work(CPUState *cs)
 {
-    return cs->interrupt_request &
+    ARMCPU *cpu = ARM_CPU(cs);
+
+    return !cpu->powered_off && cs->interrupt_request &
         (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB);
 }

@@ -91,6 +93,9 @@ static void arm_cpu_reset(CPUState *s)
     env->vfp.xregs[ARM_VFP_MVFR1] = cpu->mvfr1;
     env->vfp.xregs[ARM_VFP_MVFR2] = cpu->mvfr2;

+    cpu->powered_off = cpu->start_powered_off;
+    s->halted = cpu->start_powered_off;
+
     if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
         env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q';
     }
diff --git a/target-arm/machine.c b/target-arm/machine.c
index 5092dcd..c8aa1d6 100644
--- a/target-arm/machine.c
+++ b/target-arm/machine.c
@@ -218,8 +218,8 @@ static int cpu_post_load(void *opaque, int version_id)

 const VMStateDescription vmstate_arm_cpu = {
     .name = "cpu",
-    .version_id = 17,
-    .minimum_version_id = 17,
+    .version_id = 18,
+    .minimum_version_id = 18,
     .pre_save = cpu_pre_save,
     .post_load = cpu_post_load,
     .fields = (VMStateField[]) {
@@ -259,6 +259,7 @@ const VMStateDescription vmstate_arm_cpu = {
         VMSTATE_UINT64(env.exception.vaddress, ARMCPU),
         VMSTATE_TIMER(gt_timer[GTIMER_PHYS], ARMCPU),
         VMSTATE_TIMER(gt_timer[GTIMER_VIRT], ARMCPU),
+        VMSTATE_BOOL(powered_off, ARMCPU),
         VMSTATE_END_OF_LIST()
     },
     .subsections = (VMStateSubsection[]) {
--
1.9.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH v2 3/6] target-arm: add hvc and smc exception emulation handling infrastructure
  2014-05-23  2:30 [Qemu-devel] [PATCH v2 0/6] ARM: add PSCI emulation support Rob Herring
  2014-05-23  2:30 ` [Qemu-devel] [PATCH v2 1/6] target-arm: don't set cpu do_interrupt handler for user mode emulation Rob Herring
  2014-05-23  2:30 ` [Qemu-devel] [PATCH v2 2/6] target-arm: add powered off cpu state Rob Herring
@ 2014-05-23  2:30 ` Rob Herring
  2014-05-26  4:25   ` Edgar E. Iglesias
  2014-06-03 14:44   ` Peter Maydell
  2014-05-23  2:30 ` [Qemu-devel] [PATCH v2 4/6] target-arm: add emulation of PSCI calls for system emulation Rob Herring
                   ` (2 subsequent siblings)
  5 siblings, 2 replies; 17+ messages in thread
From: Rob Herring @ 2014-05-23  2:30 UTC (permalink / raw
  To: Peter Maydell
  Cc: Rob Herring, Peter Crosthwaite, qemu-devel, Christoffer Dall

From: Rob Herring <rob.herring@linaro.org>

Add the infrastructure to handle and emulate hvc and smc exceptions.
This will enable emulation of things such as PSCI calls. This commit
does not change the behavior and will exit with unknown exception.

Signed-off-by: Rob Herring <rob.herring@linaro.org>
---
v2:
- add syn_aa32_smc
- add missing syndrome calls
- properly handle unhandled SMC/HVC emulation as undefined instruction
  exception
- Move PSCI bits in arm_cpu_do_hvc/smc to next patch
- fix immediate value for thumb hvc

 target-arm/cpu-qom.h       |  3 +++
 target-arm/cpu.h           |  2 ++
 target-arm/helper-a64.c    | 32 ++++++++++++++++++++++++++++----
 target-arm/helper.c        | 30 ++++++++++++++++++++++++++++++
 target-arm/internals.h     | 20 ++++++++++++++++++++
 target-arm/translate-a64.c | 13 ++++++++++---
 target-arm/translate.c     | 24 +++++++++++++++++-------
 7 files changed, 110 insertions(+), 14 deletions(-)

diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index f835900..d2ff087 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -195,6 +195,9 @@ extern const struct VMStateDescription vmstate_arm_cpu;
 void register_cp_regs_for_features(ARMCPU *cpu);
 void init_cpreg_list(ARMCPU *cpu);

+bool arm_cpu_do_hvc(CPUState *cs);
+bool arm_cpu_do_smc(CPUState *cs);
+
 void arm_cpu_do_interrupt(CPUState *cpu);
 void arm_v7m_cpu_do_interrupt(CPUState *cpu);

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index c83f249..905ba02 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -51,6 +51,8 @@
 #define EXCP_EXCEPTION_EXIT  8   /* Return from v7M exception.  */
 #define EXCP_KERNEL_TRAP     9   /* Jumped to kernel code page.  */
 #define EXCP_STREX          10
+#define EXCP_HVC            11
+#define EXCP_SMC            12

 #define ARMV7M_EXCP_RESET   1
 #define ARMV7M_EXCP_NMI     2
diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
index 84411b4..e3dcca8 100644
--- a/target-arm/helper-a64.c
+++ b/target-arm/helper-a64.c
@@ -466,14 +466,11 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
                       env->exception.syndrome);
     }

-    env->cp15.esr_el1 = env->exception.syndrome;
-    env->cp15.far_el1 = env->exception.vaddress;
-
     switch (cs->exception_index) {
     case EXCP_PREFETCH_ABORT:
     case EXCP_DATA_ABORT:
         qemu_log_mask(CPU_LOG_INT, "...with FAR 0x%" PRIx64 "\n",
-                      env->cp15.far_el1);
+                      env->exception.vaddress);
         break;
     case EXCP_BKPT:
     case EXCP_UDEF:
@@ -485,10 +482,37 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
     case EXCP_FIQ:
         addr += 0x100;
         break;
+    case EXCP_HVC:
+        if (arm_cpu_do_hvc(cs)) {
+            return;
+        }
+        qemu_log_mask(LOG_GUEST_ERROR, "Unhandled HVC exception\n");
+        env->exception.syndrome = syn_uncategorized();
+        if (is_a64(env)) {
+            env->pc -= 4;
+        } else {
+            env->regs[15] -= 4;
+        }
+        break;
+    case EXCP_SMC:
+        if (arm_cpu_do_smc(cs)) {
+            return;
+        }
+        qemu_log_mask(LOG_GUEST_ERROR, "Unhandled SMC exception\n");
+        env->exception.syndrome = syn_uncategorized();
+        if (is_a64(env)) {
+            env->pc -= 4;
+        } else {
+            env->regs[15] -= 4;
+        }
+        break;
     default:
         cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
     }

+    env->cp15.esr_el1 = env->exception.syndrome;
+    env->cp15.far_el1 = env->exception.vaddress;
+
     if (is_a64(env)) {
         env->banked_spsr[0] = pstate_read(env);
         env->sp_el[arm_current_pl(env)] = env->xregs[31];
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 1307473..552e601 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3255,6 +3255,16 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
     env->thumb = addr & 1;
 }

+bool arm_cpu_do_hvc(CPUState *cs)
+{
+    return false;
+}
+
+bool arm_cpu_do_smc(CPUState *cs)
+{
+    return false;
+}
+
 /* Handle a CPU exception.  */
 void arm_cpu_do_interrupt(CPUState *cs)
 {
@@ -3357,6 +3367,26 @@ void arm_cpu_do_interrupt(CPUState *cs)
         mask = CPSR_A | CPSR_I | CPSR_F;
         offset = 4;
         break;
+    case EXCP_HVC:
+        if (arm_cpu_do_hvc(cs)) {
+            return;
+        }
+        qemu_log_mask(LOG_GUEST_ERROR, "Unhandled HVC exception\n");
+        new_mode = ARM_CPU_MODE_UND;
+        addr = 0x04;
+        mask = CPSR_A | CPSR_I;
+        offset = 4;
+       break;
+    case EXCP_SMC:
+        if (arm_cpu_do_smc(cs)) {
+            return;
+        }
+        qemu_log_mask(LOG_GUEST_ERROR, "Unhandled SMC exception\n");
+        new_mode = ARM_CPU_MODE_UND;
+        addr = 0x04;
+        mask = CPSR_A | CPSR_I;
+        offset = 4;
+        break;
     default:
         cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
         return; /* Never happens.  Keep compiler happy.  */
diff --git a/target-arm/internals.h b/target-arm/internals.h
index d63a975..52a284f 100644
--- a/target-arm/internals.h
+++ b/target-arm/internals.h
@@ -184,6 +184,26 @@ static inline uint32_t syn_aa32_svc(uint32_t imm16, bool is_thumb)
         | (is_thumb ? 0 : ARM_EL_IL);
 }

+static inline uint32_t syn_aa64_hvc(uint32_t imm16)
+{
+    return (EC_AA64_HVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
+}
+
+static inline uint32_t syn_aa32_hvc(uint32_t imm16)
+{
+    return (EC_AA32_HVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
+}
+
+static inline uint32_t syn_aa64_smc(uint32_t imm16)
+{
+    return (EC_AA64_SMC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
+}
+
+static inline uint32_t syn_aa32_smc(void)
+{
+    return (EC_AA32_SMC << ARM_EL_EC_SHIFT) | ARM_EL_IL;
+}
+
 static inline uint32_t syn_aa64_bkpt(uint32_t imm16)
 {
     return (EC_AA64_BKPT << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index b62db4d..d5e3624 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1449,11 +1449,18 @@ static void disas_exc(DisasContext *s, uint32_t insn)
         /* SVC, HVC, SMC; since we don't support the Virtualization
          * or TrustZone extensions these all UNDEF except SVC.
          */
-        if (op2_ll != 1) {
-            unallocated_encoding(s);
+        switch (op2_ll) {
+        case 1:
+            gen_exception_insn(s, 0, EXCP_SWI, syn_aa64_svc(imm16));
+            break;
+        case 2:
+            gen_exception_insn(s, 0, EXCP_HVC, syn_aa64_hvc(imm16));
+            break;
+        case 3:
+            gen_exception_insn(s, 0, EXCP_SMC, syn_aa64_smc(imm16));
             break;
         }
-        gen_exception_insn(s, 0, EXCP_SWI, syn_aa64_svc(imm16));
+        unallocated_encoding(s);
         break;
     case 1:
         if (op2_ll != 0) {
diff --git a/target-arm/translate.c b/target-arm/translate.c
index a4d920b..c108bc7 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -7727,9 +7727,14 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
         case 7:
         {
             int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
-            /* SMC instruction (op1 == 3)
-               and undefined instructions (op1 == 0 || op1 == 2)
-               will trap */
+            /* HVC and SMC instructions */
+            if (op1 == 2) {
+                gen_exception_insn(s, 0, EXCP_HVC, syn_aa32_hvc(imm16));
+                break;
+            } else if (op1 == 3) {
+                gen_exception_insn(s, 0, EXCP_SMC, syn_aa32_smc());
+                break;
+            }
             if (op1 != 1) {
                 goto illegal_op;
             }
@@ -9555,10 +9560,15 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
                     goto illegal_op;

                 if (insn & (1 << 26)) {
-                    /* Secure monitor call (v6Z) */
-                    qemu_log_mask(LOG_UNIMP,
-                                  "arm: unimplemented secure monitor call\n");
-                    goto illegal_op; /* not implemented.  */
+                    if (!(insn & (1 << 20))) {
+                        /* Hypervisor call (v7) */
+                        uint32_t imm16 = extract32(insn, 0, 12);
+                        imm16 |= extract32(insn, 16, 4) << 12;
+                        gen_exception_insn(s, 0, EXCP_HVC, syn_aa32_hvc(imm16));
+                    } else {
+                        /* Secure monitor call (v6+) */
+                        gen_exception_insn(s, 0, EXCP_SMC, syn_aa32_smc());
+                    }
                 } else {
                     op = (insn >> 20) & 7;
                     switch (op) {
--
1.9.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH v2 4/6] target-arm: add emulation of PSCI calls for system emulation
  2014-05-23  2:30 [Qemu-devel] [PATCH v2 0/6] ARM: add PSCI emulation support Rob Herring
                   ` (2 preceding siblings ...)
  2014-05-23  2:30 ` [Qemu-devel] [PATCH v2 3/6] target-arm: add hvc and smc exception emulation handling infrastructure Rob Herring
@ 2014-05-23  2:30 ` Rob Herring
  2014-06-03 11:14   ` Peter Maydell
  2014-05-23  2:30 ` [Qemu-devel] [PATCH v2 5/6] arm/virt: enable PSCI emulation support " Rob Herring
  2014-05-23  2:30 ` [Qemu-devel] [PATCH v2 6/6] arm/highbank: enable PSCI emulation support Rob Herring
  5 siblings, 1 reply; 17+ messages in thread
From: Rob Herring @ 2014-05-23  2:30 UTC (permalink / raw
  To: Peter Maydell
  Cc: Rob Herring, Peter Crosthwaite, qemu-devel, Christoffer Dall

From: Rob Herring <rob.herring@linaro.org>

Add support for handling PSCI calls in system emulation. Both version
0.1 and 0.2 of the PSCI spec are supported. Platforms can enable support
by setting "psci-method" QOM property on the cpus to SMC or HVC
emulation and having PSCI binding in their dtb.

Signed-off-by: Rob Herring <rob.herring@linaro.org>
---
v2:
- Add reference to PSCI spec
- Add target_cs instead of cs when doing operations on a different core.
- Move arm_cpu_do_hvc/smc contents from previous patch.
- Set context_id on both x0 and r0.

 target-arm/Makefile.objs |   2 +-
 target-arm/cpu-qom.h     |   6 ++
 target-arm/cpu.c         |   1 +
 target-arm/helper.c      |  12 ++++
 target-arm/kvm-consts.h  |   6 ++
 target-arm/psci.c        | 157 +++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 183 insertions(+), 1 deletion(-)
 create mode 100644 target-arm/psci.c

diff --git a/target-arm/Makefile.objs b/target-arm/Makefile.objs
index dcd167e..50f6c43 100644
--- a/target-arm/Makefile.objs
+++ b/target-arm/Makefile.objs
@@ -1,5 +1,5 @@
 obj-y += arm-semi.o
-obj-$(CONFIG_SOFTMMU) += machine.o
+obj-$(CONFIG_SOFTMMU) += machine.o psci.o
 obj-$(CONFIG_KVM) += kvm.o
 obj-$(call land,$(CONFIG_KVM),$(call lnot,$(TARGET_AARCH64))) += kvm32.o
 obj-$(call land,$(CONFIG_KVM),$(TARGET_AARCH64)) += kvm64.o
diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index d2ff087..56999f1 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -105,6 +105,11 @@ typedef struct ARMCPU {
     /* CPU currently in PSCI powered-off state */
     bool powered_off;

+    /* PSCI emulation state
+     * 0 - disabled, 1 - smc, 2 - hvc
+     */
+    uint32_t psci_method;
+
     /* [QEMU_]KVM_ARM_TARGET_* constant for this CPU, or
      * QEMU_KVM_ARM_TARGET_NONE if the kernel doesn't support this CPU type.
      */
@@ -195,6 +200,7 @@ extern const struct VMStateDescription vmstate_arm_cpu;
 void register_cp_regs_for_features(ARMCPU *cpu);
 void init_cpreg_list(ARMCPU *cpu);

+bool arm_handle_psci(CPUState *cs);
 bool arm_cpu_do_hvc(CPUState *cs);
 bool arm_cpu_do_smc(CPUState *cs);

diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index a0f9916..64f1157 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -1024,6 +1024,7 @@ static const ARMCPUInfo arm_cpus[] = {

 static Property arm_cpu_properties[] = {
     DEFINE_PROP_BOOL("start-powered-off", ARMCPU, start_powered_off, false),
+    DEFINE_PROP_UINT32("psci-method", ARMCPU, psci_method, 0),
     DEFINE_PROP_UINT32("midr", ARMCPU, midr, 0),
     DEFINE_PROP_END_OF_LIST()
 };
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 552e601..c1be201 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3257,11 +3257,23 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)

 bool arm_cpu_do_hvc(CPUState *cs)
 {
+    ARMCPU *cpu = ARM_CPU(cs);
+
+    if (cpu->psci_method == QEMU_PSCI_METHOD_HVC) {
+        return arm_handle_psci(cs);
+    }
+
     return false;
 }

 bool arm_cpu_do_smc(CPUState *cs)
 {
+    ARMCPU *cpu = ARM_CPU(cs);
+
+    if (cpu->psci_method == QEMU_PSCI_METHOD_SMC) {
+        return arm_handle_psci(cs);
+    }
+
     return false;
 }

diff --git a/target-arm/kvm-consts.h b/target-arm/kvm-consts.h
index 6009a33..d25b9b8 100644
--- a/target-arm/kvm-consts.h
+++ b/target-arm/kvm-consts.h
@@ -50,6 +50,12 @@ MISMATCH_CHECK(PSCI_FN_CPU_OFF, KVM_PSCI_FN_CPU_OFF)
 MISMATCH_CHECK(PSCI_FN_CPU_ON, KVM_PSCI_FN_CPU_ON)
 MISMATCH_CHECK(PSCI_FN_MIGRATE, KVM_PSCI_FN_MIGRATE)

+enum {
+    QEMU_PSCI_METHOD_DISABLED = 0,
+    QEMU_PSCI_METHOD_SMC = 1,
+    QEMU_PSCI_METHOD_HVC = 2,
+};
+
 /* Note that KVM uses overlapping values for AArch32 and AArch64
  * target CPU numbers. AArch32 targets:
  */
diff --git a/target-arm/psci.c b/target-arm/psci.c
new file mode 100644
index 0000000..88af3f9
--- /dev/null
+++ b/target-arm/psci.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2014 - Linaro
+ * Author: Rob Herring <rob.herring@linaro.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <cpu.h>
+#include <cpu-qom.h>
+#include <kvm-consts.h>
+#include <sysemu/sysemu.h>
+#include <linux/psci.h>
+
+/*
+ * This function implements emulation of ARM Power State Coordination
+ * Interface (PSCI) version 0.2. Details of the PSCI functionality can be
+ * found at:
+ * http://infocenter.arm.com/help//topic/com.arm.doc.den0022b/index.html
+ */
+bool arm_handle_psci(CPUState *cs)
+{
+    CPUState *target_cs;
+    CPUClass *cc;
+    ARMCPU *cpu = ARM_CPU(cs);
+    CPUARMState *env = &cpu->env;
+    uint64_t param[4];
+    uint64_t context_id, mpidr;
+    target_ulong entry;
+    int32_t ret = 0;
+    int i;
+
+    for (i = 0; i < 4; i++) {
+        /* Zero extending registers on 32-bit is okay for PSCI */
+        param[i] = is_a64(env) ? env->xregs[i] : env->regs[i];
+    }
+
+    if ((param[0] & PSCI_0_2_64BIT) && !is_a64(env)) {
+        ret = PSCI_RET_INVALID_PARAMS;
+        goto err;
+    }
+
+    switch (param[0]) {
+    case PSCI_0_2_FN_PSCI_VERSION:
+        ret = PSCI_VERSION_MAJOR(0) | PSCI_VERSION_MINOR(2);
+        break;
+    case PSCI_0_2_FN_MIGRATE_INFO_TYPE:
+        ret = PSCI_0_2_TOS_MP;    /* No trusted OS */
+        break;
+    case PSCI_0_2_FN_AFFINITY_INFO:
+    case PSCI_0_2_FN64_AFFINITY_INFO:
+        mpidr = param[1];
+
+        switch (param[2]) {
+        case 0:
+            /* Get the target cpu */
+            target_cs = qemu_get_cpu(mpidr & 0xff);
+            if (!target_cs) {
+                ret = PSCI_RET_INVALID_PARAMS;
+                break;
+            }
+            cpu = ARM_CPU(target_cs);
+            ret = cpu->powered_off ? 1 : 0;
+            break;
+        default:
+            /* Everything above affinity level 0 is always on. */
+            ret = 0;
+        }
+        break;
+    case PSCI_0_2_FN_SYSTEM_RESET:
+        qemu_system_reset_request();
+        break;
+    case PSCI_0_2_FN_SYSTEM_OFF:
+        qemu_system_powerdown_request();
+        break;
+    case PSCI_FN_CPU_ON:
+    case PSCI_0_2_FN_CPU_ON:
+    case PSCI_0_2_FN64_CPU_ON:
+        mpidr = param[1];
+        entry = param[2];
+        context_id = param[3];
+
+        /* change to the cpu we are powering up */
+        target_cs = qemu_get_cpu(mpidr & 0xff);
+        if (!target_cs) {
+            ret = PSCI_RET_INVALID_PARAMS;
+            break;
+        }
+        cpu = ARM_CPU(target_cs);
+
+        if (!cpu->powered_off) {
+            ret = PSCI_RET_ALREADY_ON;
+            break;
+        }
+
+        /* Initialize the cpu we are turning on */
+        cpu_reset(target_cs);
+        cc = CPU_GET_CLASS(target_cs);
+        cc->set_pc(target_cs, entry);
+
+        cpu->powered_off = false;
+        target_cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
+
+        /* Set the context_id in r0/x0 */
+        cpu->env.xregs[0] = cpu->env.regs[0] = context_id;
+
+        ret = 0;
+        break;
+    case PSCI_FN_CPU_OFF:
+    case PSCI_0_2_FN_CPU_OFF:
+        cpu->powered_off = true;
+        cs->exit_request = 1;
+        cs->halted = 1;
+
+        /* CPU_OFF should never return, but if it does return an error */
+        ret = PSCI_RET_DENIED;
+        break;
+    case PSCI_FN_CPU_SUSPEND:
+    case PSCI_0_2_FN_CPU_SUSPEND:
+    case PSCI_0_2_FN64_CPU_SUSPEND:
+        /* Affinity levels are not supported in QEMU */
+        if (param[1] & 0xfffe0000) {
+            ret = PSCI_RET_INVALID_PARAMS;
+            break;
+        }
+        /* Powerdown is not supported, we always go into WFI */
+        cs->halted = 1;
+        cs->exit_request = 1;
+
+        /* Return success when we wakeup */
+        ret = 0;
+        break;
+    case PSCI_FN_MIGRATE:
+    case PSCI_0_2_FN_MIGRATE:
+        ret = PSCI_RET_NOT_SUPPORTED;
+        break;
+    default:
+        return false;
+    }
+
+err:
+    if (is_a64(env)) {
+        env->xregs[0] = ret;
+    } else {
+        env->regs[0] = ret;
+    }
+    return true;
+}
--
1.9.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH v2 5/6] arm/virt: enable PSCI emulation support for system emulation
  2014-05-23  2:30 [Qemu-devel] [PATCH v2 0/6] ARM: add PSCI emulation support Rob Herring
                   ` (3 preceding siblings ...)
  2014-05-23  2:30 ` [Qemu-devel] [PATCH v2 4/6] target-arm: add emulation of PSCI calls for system emulation Rob Herring
@ 2014-05-23  2:30 ` Rob Herring
  2014-06-03 14:43   ` Peter Maydell
  2014-05-23  2:30 ` [Qemu-devel] [PATCH v2 6/6] arm/highbank: enable PSCI emulation support Rob Herring
  5 siblings, 1 reply; 17+ messages in thread
From: Rob Herring @ 2014-05-23  2:30 UTC (permalink / raw
  To: Peter Maydell
  Cc: Rob Herring, Peter Crosthwaite, qemu-devel, Christoffer Dall

From: Rob Herring <rob.herring@linaro.org>

Now that we have PSCI emulation, enable it for the virt platform.
This simplifies the virt machine a bit now that PSCI and SMP no longer
need to be KVM only features.

Signed-off-by: Rob Herring <rob.herring@linaro.org>
---
v2:
- Rebased. Mostly a whitespace change removing the kvm_enabled() check.

 hw/arm/virt.c | 41 +++++++++++++++--------------------------
 1 file changed, 15 insertions(+), 26 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 442363c..e58a07a 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -187,23 +187,19 @@ static void fdt_add_psci_node(const VirtBoardInfo *vbi)
     void *fdt = vbi->fdt;
     ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(0));

-    /* No PSCI for TCG yet */
-    if (kvm_enabled()) {
-        qemu_fdt_add_subnode(fdt, "/psci");
-        if (armcpu->psci_version == 2) {
-            const char comp[] = "arm,psci-0.2\0arm,psci";
-            qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
-        } else {
-            qemu_fdt_setprop_string(fdt, "/psci", "compatible", "arm,psci");
-        }
-
-        qemu_fdt_setprop_string(fdt, "/psci", "method", "hvc");
-        qemu_fdt_setprop_cell(fdt, "/psci", "cpu_suspend",
-                                  PSCI_FN_CPU_SUSPEND);
-        qemu_fdt_setprop_cell(fdt, "/psci", "cpu_off", PSCI_FN_CPU_OFF);
-        qemu_fdt_setprop_cell(fdt, "/psci", "cpu_on", PSCI_FN_CPU_ON);
-        qemu_fdt_setprop_cell(fdt, "/psci", "migrate", PSCI_FN_MIGRATE);
+    qemu_fdt_add_subnode(fdt, "/psci");
+    if (armcpu->psci_version == 2) {
+        const char comp[] = "arm,psci-0.2\0arm,psci";
+        qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
+    } else {
+        qemu_fdt_setprop_string(fdt, "/psci", "compatible", "arm,psci");
     }
+
+    qemu_fdt_setprop_string(fdt, "/psci", "method", "hvc");
+    qemu_fdt_setprop_cell(fdt, "/psci", "cpu_suspend", PSCI_FN_CPU_SUSPEND);
+    qemu_fdt_setprop_cell(fdt, "/psci", "cpu_off", PSCI_FN_CPU_OFF);
+    qemu_fdt_setprop_cell(fdt, "/psci", "cpu_on", PSCI_FN_CPU_ON);
+    qemu_fdt_setprop_cell(fdt, "/psci", "migrate", PSCI_FN_MIGRATE);
 }

 static void fdt_add_timer_nodes(const VirtBoardInfo *vbi)
@@ -418,16 +414,6 @@ static void machvirt_init(QEMUMachineInitArgs *args)

     vbi->smp_cpus = smp_cpus;

-    /*
-     * Only supported method of starting secondary CPUs is PSCI and
-     * PSCI is not yet supported with TCG, so limit smp_cpus to 1
-     * if we're not using KVM.
-     */
-    if (!kvm_enabled() && smp_cpus > 1) {
-        error_report("mach-virt: must enable KVM to use multiple CPUs");
-        exit(1);
-    }
-
     if (args->ram_size > vbi->memmap[VIRT_MEM].size) {
         error_report("mach-virt: cannot model more than 30GB RAM");
         exit(1);
@@ -446,6 +432,9 @@ static void machvirt_init(QEMUMachineInitArgs *args)
         }
         cpuobj = object_new(object_class_get_name(oc));

+        object_property_set_int(cpuobj, QEMU_PSCI_METHOD_HVC, "psci-method",
+                                NULL);
+
         /* Secondary CPUs start in PSCI powered-down state */
         if (n > 0) {
             object_property_set_bool(cpuobj, true, "start-powered-off", NULL);
--
1.9.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH v2 6/6] arm/highbank: enable PSCI emulation support
  2014-05-23  2:30 [Qemu-devel] [PATCH v2 0/6] ARM: add PSCI emulation support Rob Herring
                   ` (4 preceding siblings ...)
  2014-05-23  2:30 ` [Qemu-devel] [PATCH v2 5/6] arm/virt: enable PSCI emulation support " Rob Herring
@ 2014-05-23  2:30 ` Rob Herring
  2014-06-03 14:42   ` Peter Maydell
  5 siblings, 1 reply; 17+ messages in thread
From: Rob Herring @ 2014-05-23  2:30 UTC (permalink / raw
  To: Peter Maydell
  Cc: Rob Herring, Peter Crosthwaite, qemu-devel, Christoffer Dall

From: Rob Herring <rob.herring@linaro.org>

Enable PSCI emulation on highbank and midway platforms.

Note that this requires fixing the PSCI function IDs in the DTB to match
what QEMU is using. This should get fixed.

Signed-off-by: Rob Herring <rob.herring@linaro.org>
---
v2:
- Add error_abort on setting of start-powered-off.


 hw/arm/highbank.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
index 24231e5..0cbc865 100644
--- a/hw/arm/highbank.c
+++ b/hw/arm/highbank.c
@@ -241,6 +241,15 @@ static void calxeda_init(QEMUMachineInitArgs *args, enum cxmachines machine)
         cpuobj = object_new(object_class_get_name(oc));
         cpu = ARM_CPU(cpuobj);

+        object_property_set_int(cpuobj, QEMU_PSCI_METHOD_SMC, "psci-method",
+                                &error_abort);
+
+        /* Secondary CPUs start in PSCI powered-down state */
+        if (n > 0) {
+            object_property_set_bool(cpuobj, true, "start-powered-off",
+                                     &error_abort);
+        }
+
         if (object_property_find(cpuobj, "reset-cbar", NULL)) {
             object_property_set_int(cpuobj, MPCORE_PERIPHBASE,
                                     "reset-cbar", &error_abort);
--
1.9.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v2 3/6] target-arm: add hvc and smc exception emulation handling infrastructure
  2014-05-23  2:30 ` [Qemu-devel] [PATCH v2 3/6] target-arm: add hvc and smc exception emulation handling infrastructure Rob Herring
@ 2014-05-26  4:25   ` Edgar E. Iglesias
  2014-05-26  8:35     ` Peter Maydell
  2014-06-03 14:44   ` Peter Maydell
  1 sibling, 1 reply; 17+ messages in thread
From: Edgar E. Iglesias @ 2014-05-26  4:25 UTC (permalink / raw
  To: Rob Herring
  Cc: Peter Maydell, Peter Crosthwaite, qemu-devel, Christoffer Dall,
	Rob Herring

On Thu, May 22, 2014 at 09:30:06PM -0500, Rob Herring wrote:
> From: Rob Herring <rob.herring@linaro.org>
> 
> Add the infrastructure to handle and emulate hvc and smc exceptions.
> This will enable emulation of things such as PSCI calls. This commit
> does not change the behavior and will exit with unknown exception.

Hi Rob,

I've got some conflicting work but am happy to rebase on top of this.
A few comments inline.


> 
> Signed-off-by: Rob Herring <rob.herring@linaro.org>
> ---
> v2:
> - add syn_aa32_smc
> - add missing syndrome calls
> - properly handle unhandled SMC/HVC emulation as undefined instruction
>   exception
> - Move PSCI bits in arm_cpu_do_hvc/smc to next patch
> - fix immediate value for thumb hvc
> 
>  target-arm/cpu-qom.h       |  3 +++
>  target-arm/cpu.h           |  2 ++
>  target-arm/helper-a64.c    | 32 ++++++++++++++++++++++++++++----
>  target-arm/helper.c        | 30 ++++++++++++++++++++++++++++++
>  target-arm/internals.h     | 20 ++++++++++++++++++++
>  target-arm/translate-a64.c | 13 ++++++++++---
>  target-arm/translate.c     | 24 +++++++++++++++++-------
>  7 files changed, 110 insertions(+), 14 deletions(-)
> 
> diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
> index f835900..d2ff087 100644
> --- a/target-arm/cpu-qom.h
> +++ b/target-arm/cpu-qom.h
> @@ -195,6 +195,9 @@ extern const struct VMStateDescription vmstate_arm_cpu;
>  void register_cp_regs_for_features(ARMCPU *cpu);
>  void init_cpreg_list(ARMCPU *cpu);
> 
> +bool arm_cpu_do_hvc(CPUState *cs);
> +bool arm_cpu_do_smc(CPUState *cs);
> +
>  void arm_cpu_do_interrupt(CPUState *cpu);
>  void arm_v7m_cpu_do_interrupt(CPUState *cpu);
> 
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index c83f249..905ba02 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -51,6 +51,8 @@
>  #define EXCP_EXCEPTION_EXIT  8   /* Return from v7M exception.  */
>  #define EXCP_KERNEL_TRAP     9   /* Jumped to kernel code page.  */
>  #define EXCP_STREX          10
> +#define EXCP_HVC            11
> +#define EXCP_SMC            12

Can you please also populate excnames[] in internals.h?


>  #define ARMV7M_EXCP_RESET   1
>  #define ARMV7M_EXCP_NMI     2
> diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
> index 84411b4..e3dcca8 100644
> --- a/target-arm/helper-a64.c
> +++ b/target-arm/helper-a64.c
> @@ -466,14 +466,11 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
>                        env->exception.syndrome);
>      }
> 
> -    env->cp15.esr_el1 = env->exception.syndrome;
> -    env->cp15.far_el1 = env->exception.vaddress;
> -
>      switch (cs->exception_index) {
>      case EXCP_PREFETCH_ABORT:
>      case EXCP_DATA_ABORT:
>          qemu_log_mask(CPU_LOG_INT, "...with FAR 0x%" PRIx64 "\n",
> -                      env->cp15.far_el1);
> +                      env->exception.vaddress);
>          break;
>      case EXCP_BKPT:
>      case EXCP_UDEF:
> @@ -485,10 +482,37 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
>      case EXCP_FIQ:
>          addr += 0x100;
>          break;
> +    case EXCP_HVC:
> +        if (arm_cpu_do_hvc(cs)) {
> +            return;
> +        }
> +        qemu_log_mask(LOG_GUEST_ERROR, "Unhandled HVC exception\n");
> +        env->exception.syndrome = syn_uncategorized();
> +        if (is_a64(env)) {
> +            env->pc -= 4;
> +        } else {
> +            env->regs[15] -= 4;
> +        }
> +        break;
> +    case EXCP_SMC:
> +        if (arm_cpu_do_smc(cs)) {
> +            return;
> +        }
> +        qemu_log_mask(LOG_GUEST_ERROR, "Unhandled SMC exception\n");
> +        env->exception.syndrome = syn_uncategorized();
> +        if (is_a64(env)) {
> +            env->pc -= 4;
> +        } else {
> +            env->regs[15] -= 4;
> +        }
> +        break;
>      default:
>          cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
>      }
> 
> +    env->cp15.esr_el1 = env->exception.syndrome;
> +    env->cp15.far_el1 = env->exception.vaddress;

I've had to change the unconditional updates of ESR and FAR, not all
exception kinds update both or any. Don't know if you want to fix up
all the combos in this series but SMC and HVC should not update FAR
AFAICT.

Cheers,
Edgar



> +
>      if (is_a64(env)) {
>          env->banked_spsr[0] = pstate_read(env);
>          env->sp_el[arm_current_pl(env)] = env->xregs[31];
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index 1307473..552e601 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -3255,6 +3255,16 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
>      env->thumb = addr & 1;
>  }
> 
> +bool arm_cpu_do_hvc(CPUState *cs)
> +{
> +    return false;
> +}
> +
> +bool arm_cpu_do_smc(CPUState *cs)
> +{
> +    return false;
> +}
> +
>  /* Handle a CPU exception.  */
>  void arm_cpu_do_interrupt(CPUState *cs)
>  {
> @@ -3357,6 +3367,26 @@ void arm_cpu_do_interrupt(CPUState *cs)
>          mask = CPSR_A | CPSR_I | CPSR_F;
>          offset = 4;
>          break;
> +    case EXCP_HVC:
> +        if (arm_cpu_do_hvc(cs)) {
> +            return;
> +        }
> +        qemu_log_mask(LOG_GUEST_ERROR, "Unhandled HVC exception\n");
> +        new_mode = ARM_CPU_MODE_UND;
> +        addr = 0x04;
> +        mask = CPSR_A | CPSR_I;
> +        offset = 4;
> +       break;
> +    case EXCP_SMC:
> +        if (arm_cpu_do_smc(cs)) {
> +            return;
> +        }
> +        qemu_log_mask(LOG_GUEST_ERROR, "Unhandled SMC exception\n");
> +        new_mode = ARM_CPU_MODE_UND;
> +        addr = 0x04;
> +        mask = CPSR_A | CPSR_I;
> +        offset = 4;
> +        break;
>      default:
>          cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
>          return; /* Never happens.  Keep compiler happy.  */
> diff --git a/target-arm/internals.h b/target-arm/internals.h
> index d63a975..52a284f 100644
> --- a/target-arm/internals.h
> +++ b/target-arm/internals.h
> @@ -184,6 +184,26 @@ static inline uint32_t syn_aa32_svc(uint32_t imm16, bool is_thumb)
>          | (is_thumb ? 0 : ARM_EL_IL);
>  }
> 
> +static inline uint32_t syn_aa64_hvc(uint32_t imm16)
> +{
> +    return (EC_AA64_HVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
> +}
> +
> +static inline uint32_t syn_aa32_hvc(uint32_t imm16)
> +{
> +    return (EC_AA32_HVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
> +}
> +
> +static inline uint32_t syn_aa64_smc(uint32_t imm16)
> +{
> +    return (EC_AA64_SMC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
> +}
> +
> +static inline uint32_t syn_aa32_smc(void)
> +{
> +    return (EC_AA32_SMC << ARM_EL_EC_SHIFT) | ARM_EL_IL;
> +}
> +
>  static inline uint32_t syn_aa64_bkpt(uint32_t imm16)
>  {
>      return (EC_AA64_BKPT << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
> diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
> index b62db4d..d5e3624 100644
> --- a/target-arm/translate-a64.c
> +++ b/target-arm/translate-a64.c
> @@ -1449,11 +1449,18 @@ static void disas_exc(DisasContext *s, uint32_t insn)
>          /* SVC, HVC, SMC; since we don't support the Virtualization
>           * or TrustZone extensions these all UNDEF except SVC.
>           */
> -        if (op2_ll != 1) {
> -            unallocated_encoding(s);
> +        switch (op2_ll) {
> +        case 1:
> +            gen_exception_insn(s, 0, EXCP_SWI, syn_aa64_svc(imm16));
> +            break;
> +        case 2:
> +            gen_exception_insn(s, 0, EXCP_HVC, syn_aa64_hvc(imm16));
> +            break;
> +        case 3:
> +            gen_exception_insn(s, 0, EXCP_SMC, syn_aa64_smc(imm16));
>              break;
>          }
> -        gen_exception_insn(s, 0, EXCP_SWI, syn_aa64_svc(imm16));
> +        unallocated_encoding(s);
>          break;
>      case 1:
>          if (op2_ll != 0) {
> diff --git a/target-arm/translate.c b/target-arm/translate.c
> index a4d920b..c108bc7 100644
> --- a/target-arm/translate.c
> +++ b/target-arm/translate.c
> @@ -7727,9 +7727,14 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
>          case 7:
>          {
>              int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
> -            /* SMC instruction (op1 == 3)
> -               and undefined instructions (op1 == 0 || op1 == 2)
> -               will trap */
> +            /* HVC and SMC instructions */
> +            if (op1 == 2) {
> +                gen_exception_insn(s, 0, EXCP_HVC, syn_aa32_hvc(imm16));
> +                break;
> +            } else if (op1 == 3) {
> +                gen_exception_insn(s, 0, EXCP_SMC, syn_aa32_smc());
> +                break;
> +            }
>              if (op1 != 1) {
>                  goto illegal_op;
>              }
> @@ -9555,10 +9560,15 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
>                      goto illegal_op;
> 
>                  if (insn & (1 << 26)) {
> -                    /* Secure monitor call (v6Z) */
> -                    qemu_log_mask(LOG_UNIMP,
> -                                  "arm: unimplemented secure monitor call\n");
> -                    goto illegal_op; /* not implemented.  */
> +                    if (!(insn & (1 << 20))) {
> +                        /* Hypervisor call (v7) */
> +                        uint32_t imm16 = extract32(insn, 0, 12);
> +                        imm16 |= extract32(insn, 16, 4) << 12;
> +                        gen_exception_insn(s, 0, EXCP_HVC, syn_aa32_hvc(imm16));
> +                    } else {
> +                        /* Secure monitor call (v6+) */
> +                        gen_exception_insn(s, 0, EXCP_SMC, syn_aa32_smc());
> +                    }
>                  } else {
>                      op = (insn >> 20) & 7;
>                      switch (op) {
> --
> 1.9.1
> 
> 

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v2 3/6] target-arm: add hvc and smc exception emulation handling infrastructure
  2014-05-26  4:25   ` Edgar E. Iglesias
@ 2014-05-26  8:35     ` Peter Maydell
  0 siblings, 0 replies; 17+ messages in thread
From: Peter Maydell @ 2014-05-26  8:35 UTC (permalink / raw
  To: Edgar E. Iglesias
  Cc: Rob Herring, Peter Crosthwaite, Rob Herring, QEMU Developers,
	Christoffer Dall

On 26 May 2014 05:25, Edgar E. Iglesias <edgar.iglesias@gmail.com> wrote:
> On Thu, May 22, 2014 at 09:30:06PM -0500, Rob Herring wrote:
>> From: Rob Herring <rob.herring@linaro.org>
>>
>> Add the infrastructure to handle and emulate hvc and smc exceptions.
>> This will enable emulation of things such as PSCI calls. This commit
>> does not change the behavior and will exit with unknown exception.
>
> Hi Rob,
>
> I've got some conflicting work but am happy to rebase on top of this.
> A few comments inline.

Since this series is dependent on the PSCI patchset which includes
a header update to headers which haven't hit the kernel kvm-next
branch yet, I'm currently expecting that your initial EL2/EL3 patchset
will get in first and this will be the set that needs to rebase...

thanks
-- PMM

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v2 4/6] target-arm: add emulation of PSCI calls for system emulation
  2014-05-23  2:30 ` [Qemu-devel] [PATCH v2 4/6] target-arm: add emulation of PSCI calls for system emulation Rob Herring
@ 2014-06-03 11:14   ` Peter Maydell
  2014-06-04 10:09     ` Rob Herring
  0 siblings, 1 reply; 17+ messages in thread
From: Peter Maydell @ 2014-06-03 11:14 UTC (permalink / raw
  To: Rob Herring
  Cc: Rob Herring, Peter Crosthwaite, QEMU Developers, Christoffer Dall

On 23 May 2014 03:30, Rob Herring <robherring2@gmail.com> wrote:
> From: Rob Herring <rob.herring@linaro.org>
>
> Add support for handling PSCI calls in system emulation. Both version
> 0.1 and 0.2 of the PSCI spec are supported. Platforms can enable support
> by setting "psci-method" QOM property on the cpus to SMC or HVC
> emulation and having PSCI binding in their dtb.

> diff --git a/target-arm/psci.c b/target-arm/psci.c
> new file mode 100644
> index 0000000..88af3f9
> --- /dev/null
> +++ b/target-arm/psci.c
> @@ -0,0 +1,157 @@
> +/*
> + * Copyright (C) 2014 - Linaro
> + * Author: Rob Herring <rob.herring@linaro.org>
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License as published by
> + *  the Free Software Foundation; either version 2 of the License, or
> + *  (at your option) any later version.
> + *
> + *  This program is distributed in the hope that it will be useful,
> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *  GNU General Public License for more details.
> + *
> + *  You should have received a copy of the GNU General Public License
> + *  along with this program; if not, see <http://www.gnu.org/licenses/>.
> + */
> +#include <cpu.h>
> +#include <cpu-qom.h>
> +#include <kvm-consts.h>
> +#include <sysemu/sysemu.h>
> +#include <linux/psci.h>

This won't build on non-Linux hosts: you can't assume
the linux-headers/ includes are available except within
code guarded by CONFIG_KVM.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v2 6/6] arm/highbank: enable PSCI emulation support
  2014-05-23  2:30 ` [Qemu-devel] [PATCH v2 6/6] arm/highbank: enable PSCI emulation support Rob Herring
@ 2014-06-03 14:42   ` Peter Maydell
  0 siblings, 0 replies; 17+ messages in thread
From: Peter Maydell @ 2014-06-03 14:42 UTC (permalink / raw
  To: Rob Herring
  Cc: Rob Herring, Peter Crosthwaite, QEMU Developers, Christoffer Dall

On 23 May 2014 03:30, Rob Herring <robherring2@gmail.com> wrote:
> From: Rob Herring <rob.herring@linaro.org>
>
> Enable PSCI emulation on highbank and midway platforms.
>
> Note that this requires fixing the PSCI function IDs in the DTB to match
> what QEMU is using. This should get fixed.
>
> Signed-off-by: Rob Herring <rob.herring@linaro.org>

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

-- PMM

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v2 5/6] arm/virt: enable PSCI emulation support for system emulation
  2014-05-23  2:30 ` [Qemu-devel] [PATCH v2 5/6] arm/virt: enable PSCI emulation support " Rob Herring
@ 2014-06-03 14:43   ` Peter Maydell
  0 siblings, 0 replies; 17+ messages in thread
From: Peter Maydell @ 2014-06-03 14:43 UTC (permalink / raw
  To: Rob Herring
  Cc: Rob Herring, Peter Crosthwaite, QEMU Developers, Christoffer Dall

On 23 May 2014 03:30, Rob Herring <robherring2@gmail.com> wrote:
> From: Rob Herring <rob.herring@linaro.org>
>
> Now that we have PSCI emulation, enable it for the virt platform.
> This simplifies the virt machine a bit now that PSCI and SMP no longer
> need to be KVM only features.
>
> Signed-off-by: Rob Herring <rob.herring@linaro.org>
> ---
> v2:
> - Rebased. Mostly a whitespace change removing the kvm_enabled() check.
>
> @@ -446,6 +432,9 @@ static void machvirt_init(QEMUMachineInitArgs *args)
>          }
>          cpuobj = object_new(object_class_get_name(oc));
>
> +        object_property_set_int(cpuobj, QEMU_PSCI_METHOD_HVC, "psci-method",
> +                                NULL);

Similarly to patch 6, this should use &error_abort, not NULL.
Otherwise
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v2 3/6] target-arm: add hvc and smc exception emulation handling infrastructure
  2014-05-23  2:30 ` [Qemu-devel] [PATCH v2 3/6] target-arm: add hvc and smc exception emulation handling infrastructure Rob Herring
  2014-05-26  4:25   ` Edgar E. Iglesias
@ 2014-06-03 14:44   ` Peter Maydell
  1 sibling, 0 replies; 17+ messages in thread
From: Peter Maydell @ 2014-06-03 14:44 UTC (permalink / raw
  To: Rob Herring
  Cc: Rob Herring, Peter Crosthwaite, QEMU Developers, Christoffer Dall

On 23 May 2014 03:30, Rob Herring <robherring2@gmail.com> wrote:
> From: Rob Herring <rob.herring@linaro.org>
>
> Add the infrastructure to handle and emulate hvc and smc exceptions.
> This will enable emulation of things such as PSCI calls. This commit
> does not change the behavior and will exit with unknown exception.
>
> Signed-off-by: Rob Herring <rob.herring@linaro.org>

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

(As Edgar notes, there is probably some conflict resolution
work required after rebasing.)

thanks
-- PMM

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v2 2/6] target-arm: add powered off cpu state
  2014-05-23  2:30 ` [Qemu-devel] [PATCH v2 2/6] target-arm: add powered off cpu state Rob Herring
@ 2014-06-03 14:45   ` Peter Maydell
  0 siblings, 0 replies; 17+ messages in thread
From: Peter Maydell @ 2014-06-03 14:45 UTC (permalink / raw
  To: Rob Herring
  Cc: Rob Herring, Peter Crosthwaite, QEMU Developers, Christoffer Dall

On 23 May 2014 03:30, Rob Herring <robherring2@gmail.com> wrote:
> From: Rob Herring <rob.herring@linaro.org>
>
> Add tracking of cpu power state in order to support powering off of
> cores in system emulation. The initial state is determined by the
> start-powered-off QOM property.
>
> Signed-off-by: Rob Herring <rob.herring@linaro.org>

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

-- PMM

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v2 1/6] target-arm: don't set cpu do_interrupt handler for user mode emulation
  2014-05-23  2:30 ` [Qemu-devel] [PATCH v2 1/6] target-arm: don't set cpu do_interrupt handler for user mode emulation Rob Herring
@ 2014-06-03 15:02   ` Peter Maydell
  0 siblings, 0 replies; 17+ messages in thread
From: Peter Maydell @ 2014-06-03 15:02 UTC (permalink / raw
  To: Rob Herring
  Cc: Rob Herring, Peter Crosthwaite, QEMU Developers, Christoffer Dall

On 23 May 2014 03:30, Rob Herring <robherring2@gmail.com> wrote:
> From: Rob Herring <rob.herring@linaro.org>
>
> In preparation to add system mode only calls to
> aarch64_cpu_do_interrupt, compile it for system mode only and don't set
> the do_interrupt callback for user mode emulation. User mode emulation
> should never get interrupts and thus should not have a exception handler
> function. Do the same change from AArch32 to keep them aligned.
>
> Signed-off-by: Rob Herring <rob.herring@linaro.org>

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

-- PMM

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v2 4/6] target-arm: add emulation of PSCI calls for system emulation
  2014-06-03 11:14   ` Peter Maydell
@ 2014-06-04 10:09     ` Rob Herring
  2014-06-04 10:16       ` Peter Maydell
  0 siblings, 1 reply; 17+ messages in thread
From: Rob Herring @ 2014-06-04 10:09 UTC (permalink / raw
  To: Peter Maydell
  Cc: Rob Herring, Peter Crosthwaite, QEMU Developers, Christoffer Dall

On Tue, Jun 3, 2014 at 6:14 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 23 May 2014 03:30, Rob Herring <robherring2@gmail.com> wrote:
>> From: Rob Herring <rob.herring@linaro.org>
>>
>> Add support for handling PSCI calls in system emulation. Both version
>> 0.1 and 0.2 of the PSCI spec are supported. Platforms can enable support
>> by setting "psci-method" QOM property on the cpus to SMC or HVC
>> emulation and having PSCI binding in their dtb.
>
>> diff --git a/target-arm/psci.c b/target-arm/psci.c
>> new file mode 100644
>> index 0000000..88af3f9
>> --- /dev/null
>> +++ b/target-arm/psci.c
>> @@ -0,0 +1,157 @@
>> +/*
>> + * Copyright (C) 2014 - Linaro
>> + * Author: Rob Herring <rob.herring@linaro.org>
>> + *
>> + *  This program is free software; you can redistribute it and/or modify
>> + *  it under the terms of the GNU General Public License as published by
>> + *  the Free Software Foundation; either version 2 of the License, or
>> + *  (at your option) any later version.
>> + *
>> + *  This program is distributed in the hope that it will be useful,
>> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + *  GNU General Public License for more details.
>> + *
>> + *  You should have received a copy of the GNU General Public License
>> + *  along with this program; if not, see <http://www.gnu.org/licenses/>.
>> + */
>> +#include <cpu.h>
>> +#include <cpu-qom.h>
>> +#include <kvm-consts.h>
>> +#include <sysemu/sysemu.h>
>> +#include <linux/psci.h>
>
> This won't build on non-Linux hosts: you can't assume
> the linux-headers/ includes are available except within
> code guarded by CONFIG_KVM.

What do you suggest doing here then. Really, psci.h is OS independent.
Can we copy it to somewhere else in the qemu tree?

Rob

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v2 4/6] target-arm: add emulation of PSCI calls for system emulation
  2014-06-04 10:09     ` Rob Herring
@ 2014-06-04 10:16       ` Peter Maydell
  0 siblings, 0 replies; 17+ messages in thread
From: Peter Maydell @ 2014-06-04 10:16 UTC (permalink / raw
  To: Rob Herring
  Cc: Rob Herring, Peter Crosthwaite, QEMU Developers, Christoffer Dall

On 4 June 2014 11:09, Rob Herring <robherring2@gmail.com> wrote:
> On Tue, Jun 3, 2014 at 6:14 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
>> This won't build on non-Linux hosts: you can't assume
>> the linux-headers/ includes are available except within
>> code guarded by CONFIG_KVM.
>
> What do you suggest doing here then. Really, psci.h is OS independent.
> Can we copy it to somewhere else in the qemu tree?

Only if you can guarantee that it won't clash with the one that is
in the linux-headers/ tree, or the one in /usr/include, ie that it
doesn't matter which of those three we pick up. That pretty much
means "kernel KVM headers can't ever rely on new PSCI
constants being added to psci.h" so that doesn't seem like it's
going to work. Otherwise it would need to be
copy-and-rename-symbols, same as we do for anything else
where we need them outside the KVM code. I agree that's pretty
ugly.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2014-06-04 10:17 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-05-23  2:30 [Qemu-devel] [PATCH v2 0/6] ARM: add PSCI emulation support Rob Herring
2014-05-23  2:30 ` [Qemu-devel] [PATCH v2 1/6] target-arm: don't set cpu do_interrupt handler for user mode emulation Rob Herring
2014-06-03 15:02   ` Peter Maydell
2014-05-23  2:30 ` [Qemu-devel] [PATCH v2 2/6] target-arm: add powered off cpu state Rob Herring
2014-06-03 14:45   ` Peter Maydell
2014-05-23  2:30 ` [Qemu-devel] [PATCH v2 3/6] target-arm: add hvc and smc exception emulation handling infrastructure Rob Herring
2014-05-26  4:25   ` Edgar E. Iglesias
2014-05-26  8:35     ` Peter Maydell
2014-06-03 14:44   ` Peter Maydell
2014-05-23  2:30 ` [Qemu-devel] [PATCH v2 4/6] target-arm: add emulation of PSCI calls for system emulation Rob Herring
2014-06-03 11:14   ` Peter Maydell
2014-06-04 10:09     ` Rob Herring
2014-06-04 10:16       ` Peter Maydell
2014-05-23  2:30 ` [Qemu-devel] [PATCH v2 5/6] arm/virt: enable PSCI emulation support " Rob Herring
2014-06-03 14:43   ` Peter Maydell
2014-05-23  2:30 ` [Qemu-devel] [PATCH v2 6/6] arm/highbank: enable PSCI emulation support Rob Herring
2014-06-03 14:42   ` Peter Maydell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.