diff mbox

[v2,4/6] arm: add a function to invoke the PSCI handler

Message ID 1385982538-17855-5-git-send-email-andre.przywara@linaro.org
State New
Headers show

Commit Message

Andre Przywara Dec. 2, 2013, 11:08 a.m. UTC
The PSCI handler is invoked via a secure monitor call with the
arguments defined in registers. Copy the function from the
Linux code and adjust it to work on both ARM32 and ARM64.

Signed-off-by: Andre Przywara <andre.przywara@linaro.org>
---
 xen/arch/arm/psci.c        | 28 ++++++++++++++++++++++++++++
 xen/include/asm-arm/psci.h |  1 +
 2 files changed, 29 insertions(+)

Comments

Ian Campbell Dec. 2, 2013, 3:07 p.m. UTC | #1
On Mon, 2013-12-02 at 12:08 +0100, Andre Przywara wrote:
> The PSCI handler is invoked via a secure monitor call with the
> arguments defined in registers. Copy the function from the
> Linux code and adjust it to work on both ARM32 and ARM64.
> 
> Signed-off-by: Andre Przywara <andre.przywara@linaro.org>
> ---
>  xen/arch/arm/psci.c        | 28 ++++++++++++++++++++++++++++
>  xen/include/asm-arm/psci.h |  1 +
>  2 files changed, 29 insertions(+)
> 
> diff --git a/xen/arch/arm/psci.c b/xen/arch/arm/psci.c
> index 9ff06cd..cc382be 100644
> --- a/xen/arch/arm/psci.c
> +++ b/xen/arch/arm/psci.c
> @@ -25,8 +25,36 @@
>  
>  int psci_available;
>  
> +#ifdef CONFIG_ARM_32
> +#define REG_PREFIX "r"
> +#else
> +#define REG_PREFIX "x"
> +#endif
> +
> +static noinline int __invoke_psci_fn_smc(u32 function_id, u32 arg0, u32 arg1,
> +                                         u32 arg2)

I should reread the PSCI spec, but are these not 64-bit on AArch64?

> +{
> +    asm volatile(
> +        __asmeq("%0", REG_PREFIX"0")
> +        __asmeq("%1", REG_PREFIX"1")
> +        __asmeq("%2", REG_PREFIX"2")
> +        __asmeq("%3", REG_PREFIX"3")
> +        "smc #0"
> +        : "+r" (function_id)
> +        : "r" (arg0), "r" (arg1), "r" (arg2));
> +
> +    return function_id;
> +}
> +
> +#undef REG_PREFIX
> +
>  static uint32_t psci_cpu_on_nr;
>  
> +int call_psci_cpu_on(int cpu, void *smp_pen)
> +{
> +    return __invoke_psci_fn_smc(psci_cpu_on_nr, cpu, __pa(smp_pen), 0);
> +}
> +
>  int __init psci_init(void)
>  {
>      struct dt_device_node *psci;
> diff --git a/xen/include/asm-arm/psci.h b/xen/include/asm-arm/psci.h
> index 2f37612..50513bf 100644
> --- a/xen/include/asm-arm/psci.h
> +++ b/xen/include/asm-arm/psci.h
> @@ -10,6 +10,7 @@
>  extern int psci_available;
>  
>  int psci_init(void);
> +int call_psci_cpu_on(int cpu, void *smp_pen);
>  
>  /* functions to handle guest PSCI requests */
>  int do_psci_cpu_on(uint32_t vcpuid, register_t entry_point);
Andre Przywara Dec. 4, 2013, 12:25 p.m. UTC | #2
On 12/02/2013 04:07 PM, Ian Campbell wrote:
> On Mon, 2013-12-02 at 12:08 +0100, Andre Przywara wrote:
>> The PSCI handler is invoked via a secure monitor call with the
>> arguments defined in registers. Copy the function from the
>> Linux code and adjust it to work on both ARM32 and ARM64.
>>
>> Signed-off-by: Andre Przywara <andre.przywara@linaro.org>
>> ---
>>   xen/arch/arm/psci.c        | 28 ++++++++++++++++++++++++++++
>>   xen/include/asm-arm/psci.h |  1 +
>>   2 files changed, 29 insertions(+)
>>
>> diff --git a/xen/arch/arm/psci.c b/xen/arch/arm/psci.c
>> index 9ff06cd..cc382be 100644
>> --- a/xen/arch/arm/psci.c
>> +++ b/xen/arch/arm/psci.c
>> @@ -25,8 +25,36 @@
>>
>>   int psci_available;
>>
>> +#ifdef CONFIG_ARM_32
>> +#define REG_PREFIX "r"
>> +#else
>> +#define REG_PREFIX "x"
>> +#endif
>> +
>> +static noinline int __invoke_psci_fn_smc(u32 function_id, u32 arg0, u32 arg1,
>> +                                         u32 arg2)
>
> I should reread the PSCI spec, but are these not 64-bit on AArch64?

Indeed. Not for all functions and parameters, but for the start address 
at least that makes sense ;-)
Is there a type in Xen which reliably holds a native word? ulong or 
something?

Thanks,
Andre.


>
>> +{
>> +    asm volatile(
>> +        __asmeq("%0", REG_PREFIX"0")
>> +        __asmeq("%1", REG_PREFIX"1")
>> +        __asmeq("%2", REG_PREFIX"2")
>> +        __asmeq("%3", REG_PREFIX"3")
>> +        "smc #0"
>> +        : "+r" (function_id)
>> +        : "r" (arg0), "r" (arg1), "r" (arg2));
>> +
>> +    return function_id;
>> +}
>> +
>> +#undef REG_PREFIX
>> +
>>   static uint32_t psci_cpu_on_nr;
>>
>> +int call_psci_cpu_on(int cpu, void *smp_pen)
>> +{
>> +    return __invoke_psci_fn_smc(psci_cpu_on_nr, cpu, __pa(smp_pen), 0);
>> +}
>> +
>>   int __init psci_init(void)
>>   {
>>       struct dt_device_node *psci;
>> diff --git a/xen/include/asm-arm/psci.h b/xen/include/asm-arm/psci.h
>> index 2f37612..50513bf 100644
>> --- a/xen/include/asm-arm/psci.h
>> +++ b/xen/include/asm-arm/psci.h
>> @@ -10,6 +10,7 @@
>>   extern int psci_available;
>>
>>   int psci_init(void);
>> +int call_psci_cpu_on(int cpu, void *smp_pen);
>>
>>   /* functions to handle guest PSCI requests */
>>   int do_psci_cpu_on(uint32_t vcpuid, register_t entry_point);
>
>
Ian Campbell Dec. 4, 2013, 12:32 p.m. UTC | #3
On Wed, 2013-12-04 at 13:25 +0100, Andre Przywara wrote:
> On 12/02/2013 04:07 PM, Ian Campbell wrote:
> > On Mon, 2013-12-02 at 12:08 +0100, Andre Przywara wrote:
> >> The PSCI handler is invoked via a secure monitor call with the
> >> arguments defined in registers. Copy the function from the
> >> Linux code and adjust it to work on both ARM32 and ARM64.
> >>
> >> Signed-off-by: Andre Przywara <andre.przywara@linaro.org>
> >> ---
> >>   xen/arch/arm/psci.c        | 28 ++++++++++++++++++++++++++++
> >>   xen/include/asm-arm/psci.h |  1 +
> >>   2 files changed, 29 insertions(+)
> >>
> >> diff --git a/xen/arch/arm/psci.c b/xen/arch/arm/psci.c
> >> index 9ff06cd..cc382be 100644
> >> --- a/xen/arch/arm/psci.c
> >> +++ b/xen/arch/arm/psci.c
> >> @@ -25,8 +25,36 @@
> >>
> >>   int psci_available;
> >>
> >> +#ifdef CONFIG_ARM_32
> >> +#define REG_PREFIX "r"
> >> +#else
> >> +#define REG_PREFIX "x"
> >> +#endif
> >> +
> >> +static noinline int __invoke_psci_fn_smc(u32 function_id, u32 arg0, u32 arg1,
> >> +                                         u32 arg2)
> >
> > I should reread the PSCI spec, but are these not 64-bit on AArch64?
> 
> Indeed. Not for all functions and parameters, but for the start address 
> at least that makes sense ;-)
> Is there a type in Xen which reliably holds a native word? ulong or 
> something?

You can use vaddr_t or register_t depending on the semantics (they are
otherwise the same). Probably register_t here.


Ian.
diff mbox

Patch

diff --git a/xen/arch/arm/psci.c b/xen/arch/arm/psci.c
index 9ff06cd..cc382be 100644
--- a/xen/arch/arm/psci.c
+++ b/xen/arch/arm/psci.c
@@ -25,8 +25,36 @@ 
 
 int psci_available;
 
+#ifdef CONFIG_ARM_32
+#define REG_PREFIX "r"
+#else
+#define REG_PREFIX "x"
+#endif
+
+static noinline int __invoke_psci_fn_smc(u32 function_id, u32 arg0, u32 arg1,
+                                         u32 arg2)
+{
+    asm volatile(
+        __asmeq("%0", REG_PREFIX"0")
+        __asmeq("%1", REG_PREFIX"1")
+        __asmeq("%2", REG_PREFIX"2")
+        __asmeq("%3", REG_PREFIX"3")
+        "smc #0"
+        : "+r" (function_id)
+        : "r" (arg0), "r" (arg1), "r" (arg2));
+
+    return function_id;
+}
+
+#undef REG_PREFIX
+
 static uint32_t psci_cpu_on_nr;
 
+int call_psci_cpu_on(int cpu, void *smp_pen)
+{
+    return __invoke_psci_fn_smc(psci_cpu_on_nr, cpu, __pa(smp_pen), 0);
+}
+
 int __init psci_init(void)
 {
     struct dt_device_node *psci;
diff --git a/xen/include/asm-arm/psci.h b/xen/include/asm-arm/psci.h
index 2f37612..50513bf 100644
--- a/xen/include/asm-arm/psci.h
+++ b/xen/include/asm-arm/psci.h
@@ -10,6 +10,7 @@ 
 extern int psci_available;
 
 int psci_init(void);
+int call_psci_cpu_on(int cpu, void *smp_pen);
 
 /* functions to handle guest PSCI requests */
 int do_psci_cpu_on(uint32_t vcpuid, register_t entry_point);