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

Re: [PATCH v3 1/6] xen/arm: firmware: Add SCMI over SMC calls handling layer


  • To: Michal Orzel <michal.orzel@xxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxxx
  • From: Andrei Cherechesu <andrei.cherechesu@xxxxxxxxxxx>
  • Date: Thu, 19 Dec 2024 12:02:47 +0200
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oss.nxp.com; dmarc=pass action=none header.from=oss.nxp.com; dkim=pass header.d=oss.nxp.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=QK1C1SuFyM8QJxGneRzCFJCjyqz4CB8QTpVoXs1AB0E=; b=EPBtI9SJiSY5Hlf2wDoHicQudvswWE/XF/KyN3WCRhY0ls7Tctccogo3uUqk4CQK2WO9/UAaBavhg8AqzNYoz94tuNWuHDe3OlHB6DiLX5B71B23aEMce5Pxr+PhTki9pI44JcEgVGQjTHyvmcItuVDdWFtIXbECiiOyoHbtA/damRAgZ/3V5jHFvqv0O/r6BX52Ir4QW/tKa4//YeLk/UEFYC06FKGHXhw/aTQ8RjhumGKfjo3RTtUH1Fy8/+jsEqm0zseNfynVWxU+VRHjkvAAznahmTh4Xc+Qn7zRSg3A2KRpVyFgnTdImVXXX7CxUaPUr1E7JUSFzCMx8kmKsw==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=ggz87eeGV5Q0vgMnhI0CJP5gcI8ifozUxtPDt5gaPzuOqJAe/TyapFe7o8CdJmnml6OVbLPjiUHJ5TyDIt7YLie1VyCTrIJhrNlx06dxX8SRddVJ4nn3kdi4j7srcHeYRR7LkKavgY5l8oxFXx0AN2mCmEVIbRQsRnBxm7bDQazwl6Y6K8/yviQV2GcpWiK2JfYKYzP6Vwk0rb3GnAKDbzOrn/DquBzHBVLU1SYcB2f7pGCEwh5vaOETDgHHAI3TwlZYXqo+y38+QKTbTt6bzwIuK22lcjEEFw58/ZkB+Vk30HkKPVYxZTSPhJcjJxEzqfRfyeiI06MuWLKQx2zBNw==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=oss.nxp.com;
  • Cc: S32@xxxxxxx, Andrei Cherechesu <andrei.cherechesu@xxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Bertrand Marquis <bertrand.marquis@xxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
  • Delivery-date: Thu, 19 Dec 2024 10:03:18 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

Hi Michal,

On 19/12/2024 10:35, Michal Orzel wrote:
>
> On 18/12/2024 15:58, Andrei Cherechesu wrote:
>>
>> Hi Michal,
>>
>> Thank you for the review.
>>
>> On 18/12/2024 16:26, Michal Orzel wrote:
>>> On 18/12/2024 11:11, Andrei Cherechesu (OSS) wrote:
>>>> From: Andrei Cherechesu <andrei.cherechesu@xxxxxxx>
>>>>
>>>> Introduce the SCMI-SMC layer to have some basic degree of
>>>> awareness about SCMI calls that are based on the ARM System
>>>> Control and Management Interface (SCMI) specification (DEN0056E).
>>>>
>>>> The SCMI specification includes various protocols for managing
>>>> system-level resources, such as: clocks, pins, reset, system power,
>>>> power domains, performance domains, etc. The clients are named
>>>> "SCMI agents" and the server is named "SCMI platform".
>>>>
>>>> Only support the shared-memory based transport with SMCs as
>>>> the doorbell mechanism for notifying the platform. Also, this
>>>> implementation only handles the "arm,scmi-smc" compatible,
>>>> requiring the following properties:
>>>>         - "arm,smc-id" (unique SMC ID)
>>>>         - "shmem" (one or more phandles pointing to shmem zones
>>>>         for each channel)
>>>>
>>>> The initialization is done as initcall, since we need
>>>> SMCs, and PSCI should already probe EL3 FW for SMCCC support.
>>>> If no "arm,scmi-smc" compatible node is found in the host
>>>> DT, the initialization fails silently, as it's not mandatory.
>>>> Otherwise, we get the 'arm,smc-id' DT property from the node,
>>>> to know the SCMI SMC ID we handle. The 'shmem' memory ranges
>>>> are not validated, as the SMC calls are only passed through
>>>> to EL3 FW if coming from the hardware domain.
>>>>
>>>> Create a new 'firmware' folder to keep the SCMI code separate
>>>> from the generic ARM code.
>>>>
>>>> Signed-off-by: Andrei Cherechesu <andrei.cherechesu@xxxxxxx>
>>>> Reviewed-by: Stefano Stabellini <sstabellini@xxxxxxxxxx>
>>>> ---
>>>>  xen/arch/arm/Kconfig                         |   2 +
>>>>  xen/arch/arm/Makefile                        |   1 +
>>>>  xen/arch/arm/firmware/Kconfig                |  13 ++
>>>>  xen/arch/arm/firmware/Makefile               |   1 +
>>>>  xen/arch/arm/firmware/scmi-smc.c             | 166 +++++++++++++++++++
>>>>  xen/arch/arm/include/asm/firmware/scmi-smc.h |  46 +++++
>>>>  6 files changed, 229 insertions(+)
>>>>  create mode 100644 xen/arch/arm/firmware/Kconfig
>>>>  create mode 100644 xen/arch/arm/firmware/Makefile
>>>>  create mode 100644 xen/arch/arm/firmware/scmi-smc.c
>>>>  create mode 100644 xen/arch/arm/include/asm/firmware/scmi-smc.h
>>>>
>>>> diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig
>>>> index 604aba4996..23dc7162a7 100644
>>>> --- a/xen/arch/arm/Kconfig
>>>> +++ b/xen/arch/arm/Kconfig
>>>> @@ -271,6 +271,8 @@ config PARTIAL_EMULATION
>>>>           not been emulated to their complete functionality. Enabling this 
>>>> might
>>>>           result in unwanted/non-spec compliant behavior.
>>>>
>>>> +source "arch/arm/firmware/Kconfig"
>>>> +
>>>>  endmenu
>>>>
>>>>  menu "ARM errata workaround via the alternative framework"
>>>> diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
>>>> index e4ad1ce851..8c696c2011 100644
>>>> --- a/xen/arch/arm/Makefile
>>>> +++ b/xen/arch/arm/Makefile
>>>> @@ -6,6 +6,7 @@ obj-$(CONFIG_HAS_PCI) += pci/
>>>>  ifneq ($(CONFIG_NO_PLAT),y)
>>>>  obj-y += platforms/
>>>>  endif
>>>> +obj-y += firmware/
>>>>  obj-$(CONFIG_TEE) += tee/
>>>>  obj-$(CONFIG_HAS_VPCI) += vpci.o
>>>>
>>>> diff --git a/xen/arch/arm/firmware/Kconfig b/xen/arch/arm/firmware/Kconfig
>>>> new file mode 100644
>>>> index 0000000000..817da745fd
>>>> --- /dev/null
>>>> +++ b/xen/arch/arm/firmware/Kconfig
>>>> @@ -0,0 +1,13 @@
>>>> +menu "Firmware Drivers"
>>>> +
>>>> +config SCMI_SMC
>>>> +       bool "Forward SCMI over SMC calls from hwdom to EL3 firmware"
>>>> +       default y
>>>> +       help
>>>> +         This option enables basic awareness for SCMI calls using SMC as
>>>> +         doorbell mechanism and Shared Memory for transport 
>>>> ("arm,scmi-smc"
>>>> +         compatible only). The value of "arm,smc-id" DT property from SCMI
>>>> +         firmware node is used to trap and forward corresponding SCMI SMCs
>>>> +         to firmware running at EL3, for calls coming from the hardware 
>>>> domain.
>>>> +
>>>> +endmenu
>>>> diff --git a/xen/arch/arm/firmware/Makefile 
>>>> b/xen/arch/arm/firmware/Makefile
>>>> new file mode 100644
>>>> index 0000000000..a5e4542666
>>>> --- /dev/null
>>>> +++ b/xen/arch/arm/firmware/Makefile
>>>> @@ -0,0 +1 @@
>>>> +obj-$(CONFIG_SCMI_SMC) += scmi-smc.o
>>>> diff --git a/xen/arch/arm/firmware/scmi-smc.c 
>>>> b/xen/arch/arm/firmware/scmi-smc.c
>>>> new file mode 100644
>>>> index 0000000000..62657308d6
>>>> --- /dev/null
>>>> +++ b/xen/arch/arm/firmware/scmi-smc.c
>>>> @@ -0,0 +1,166 @@
>>>> +/* SPDX-License-Identifier: GPL-2.0-or-later */
>>>> +/*
>>>> + * xen/arch/arm/firmware/scmi-smc.c
>>>> + *
>>>> + * ARM System Control and Management Interface (SCMI) over SMC
>>>> + * Generic handling layer
>>>> + *
>>>> + * Andrei Cherechesu <andrei.cherechesu@xxxxxxx>
>>>> + * Copyright 2024 NXP
>>>> + */
>>>> +
>>>> +#include <xen/acpi.h>
>>>> +#include <xen/device_tree.h>
>>>> +#include <xen/errno.h>
>>>> +#include <xen/init.h>
>>>> +#include <xen/sched.h>
>>>> +#include <xen/types.h>
>>>> +
>>>> +#include <asm/smccc.h>
>>>> +#include <asm/firmware/scmi-smc.h>
>>>> +
>>>> +#define SCMI_SMC_ID_PROP   "arm,smc-id"
>>>> +
>>>> +static bool __ro_after_init scmi_support;
>>> I don't understand the need for this variable. IMO it's useless, given that 
>>> in next patch you do:
>>>
>>> ...
>>> if ( scmi_is_enabled() )
>>>     return scmi_handle_smc(regs);
>>>
>>> return false;
>>>
>>> which could simply be changed to:
>>> ...
>>> return scmi_handle_smc(regs);
>>>
>>> and the variable, functions for it, etc. could be removed which would 
>>> simplify the code.
>>>
>>> [...]
>> Well, I agree that the code would maybe be simpler, but
>> that means we would call `scmi_handle_smc()` both when
>> SCMI-SMC layer is initialized and when it is not.
>>
>> That then means that if `scmi_handle_smc()` returns false,
>> we won't know in the caller if the SCMI-SMC layer is not
>> initialized at all or if it is initialized, but the SMC
>> request is invalid (it does not have the SMC ID we expect).
>> Do we need to, though?
> Let me explain more:
> scmi_handle_smc() is called from within handle_sip() that can result 
> true/false.
> If SCMI is disabled, we need to return false. If SCMI is enabled but request 
> is
> invalid we need to return false as well. If SCMI is enabled but not 
> initialized
> we also need to return false. 

Right, that's what I expressed my concern about too: that we're grouping up all
of these cases under a single return code of the same function. I'm fine with
that, though.

> I suggest to drop scmi_is_enabled() as exported
> function and only use scmi_handle_smc() as global like I did in my example.
> Now, this solves the part where SCMI is disabled since you have a stub 
> returning
> false and also the part where SCMI request is invalid. However, this does not
> solve the part where SCMI is enabled but layer not initialized. To fix it, you
> simply need to check inside scmi_handle_smc() if it's initialized. That's much
> simpler than requiring to use another global function which is not nice.

Got it, my understanding was that you suggested to completely drop the 
`scmi_support`
variable and its associated function (`scmi_is_enabled()`), and decide 
internally
whether the SCMI layer is initialized based on another mechanism. That's why I 
suggested
`scmi_smc_id != 0` as mechanism and said that it simplifies the code, but
requires maybe some non-trivial assumptions (if `scmi_smc_id == 0` => SCMI not
initialized yet).
...

>
> Diff below:
> diff --git a/xen/arch/arm/firmware/scmi-smc.c 
> b/xen/arch/arm/firmware/scmi-smc.c
> index 62657308d61d..b3f34bdbb89b 100644
> --- a/xen/arch/arm/firmware/scmi-smc.c
> +++ b/xen/arch/arm/firmware/scmi-smc.c
> @@ -24,12 +24,6 @@
>  static bool __ro_after_init scmi_support;
>  static uint32_t __ro_after_init scmi_smc_id;
>
> -/* Check if SCMI layer correctly initialized and can be used. */
> -bool scmi_is_enabled(void)
> -{
> -    return scmi_support;
> -}
> -
>  /*
>   * Check if provided SMC Function Identifier matches the one known by the 
> SCMI
>   * layer, as read from DT prop 'arm,smc-id' during initialiation.
> @@ -52,6 +46,9 @@ bool scmi_handle_smc(struct cpu_user_regs *regs)
>      uint32_t fid = (uint32_t)get_user_reg(regs, 0);
>      struct arm_smccc_res res;
>
> +    if ( !scmi_support )
> +        return false;
> +
>      if ( !scmi_is_valid_smc_id(fid) )
>          return false;
>
> diff --git a/xen/arch/arm/include/asm/firmware/scmi-smc.h 
> b/xen/arch/arm/include/asm/firmware/scmi-smc.h
> index 57cc9eef8676..58730a8037c5 100644
> --- a/xen/arch/arm/include/asm/firmware/scmi-smc.h
> +++ b/xen/arch/arm/include/asm/firmware/scmi-smc.h
> @@ -17,16 +17,10 @@
>
>  #ifdef CONFIG_SCMI_SMC
>
> -bool scmi_is_enabled(void);
>  bool scmi_handle_smc(struct cpu_user_regs *regs);
>
>  #else
>
> -static inline bool scmi_is_enabled(void)
> -{
> -    return false;
> -}
> -
>  static inline bool scmi_handle_smc(struct cpu_user_regs *regs)
>  {
>      return false;
> diff --git a/xen/arch/arm/vsmc.c b/xen/arch/arm/vsmc.c
> index c4d225c45cd3..62d8117a120c 100644
> --- a/xen/arch/arm/vsmc.c
> +++ b/xen/arch/arm/vsmc.c
> @@ -232,10 +232,7 @@ static bool handle_sip(struct cpu_user_regs *regs)
>      if ( platform_smc(regs) )
>          return true;
>
> -    if ( scmi_is_enabled() )
> -        return scmi_handle_smc(regs);
> -
> -    return false;
> +    return scmi_handle_smc(regs);
>  }
>
>  /*

...
I understand now that your suggestions were not that restrictive :).

Thank you for the clarification!
v4 is on the way.
> ~Michal
>

Regards,
Andrei Cherechesu




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.