diff mbox series

[v3,1/3] xen/arm: Add imx8q{m,x} platform glue

Message ID 20240328163351.64808-2-john.ernberg@actia.se (mailing list archive)
State Superseded
Headers show
Series Xen: ARM: Improved NXP iMX8 platform support | expand

Commit Message

John Ernberg March 28, 2024, 4:34 p.m. UTC
When using Linux for dom0 there are a bunch of drivers that need to do SMC
SIP calls into the firmware to enable certain hardware bits like the
watchdog.

Provide a basic platform glue that implements the needed SMC forwarding.

The format of these calls are as follows:
 - reg 0: function ID
 - reg 1: subfunction ID (when there's a subfunction)
 remaining regs: args

For now we only allow Dom0 to make these calls as they are all managing
hardware. There is no specification for these SIP calls, the IDs and names
have been extracted from the upstream linux kernel and the vendor kernel.

Most of the SIP calls are only available for the iMX8M series of SoCs, so
they are easy to reject and they need to be revisited when iMX8M series
support is added.

From the other calls we can reject CPUFREQ because Dom0 cannot make an
informed decision regarding CPU frequency scaling, WAKEUP_SRC is to wake
up from suspend, which Xen doesn't support at this time.

This leaves the TIME SIP, OTP SIPs, BUILDINFO SIP and TEMP ALARM SIP, which
for now are allowed to Dom0.

NOTE: This code is based on code found in NXP Xen tree located here:
https://github.com/nxp-imx/imx-xen/blob/lf-5.10.y_4.13/xen/arch/arm/platforms/imx8qm.c

Signed-off-by: Peng Fan <peng.fan@nxp.com>
[jernberg: Add SIP call filtering]
Signed-off-by: John Ernberg <john.ernberg@actia.se>

---

v3:
 - Adhere to style guidelines for line length and label indentation (Michal Orzel)
 - Use smccc macros to build the SIP function identifier (Michal Orzel)
 - Adjust platform name to be specific to QM and QXP variants (Michal Orzel)
 - Pick up additional SIPs which may be used by other Linux versions - for review purposes
 - Changes to the commit message due to above

v2:
 - Reword the commit message to be a bit clearer
 - Include the link previously added as a context note to the commit message (Julien Grall)
 - Add Pengs signed off (Julien Grall, Peng Fan)
 - Add basic SIP call filter (Julien Grall)
 - Expand the commit message a whole bunch because of the changes to the code
---
 xen/arch/arm/platforms/Makefile |   1 +
 xen/arch/arm/platforms/imx8qm.c | 168 ++++++++++++++++++++++++++++++++
 2 files changed, 169 insertions(+)
 create mode 100644 xen/arch/arm/platforms/imx8qm.c

Comments

Michal Orzel April 2, 2024, 7:24 a.m. UTC | #1
Hi John,

On 28/03/2024 17:34, John Ernberg wrote:
> 
> 
> When using Linux for dom0 there are a bunch of drivers that need to do SMC
> SIP calls into the firmware to enable certain hardware bits like the
> watchdog.
> 
> Provide a basic platform glue that implements the needed SMC forwarding.
> 
> The format of these calls are as follows:
>  - reg 0: function ID
>  - reg 1: subfunction ID (when there's a subfunction)
>  remaining regs: args
> 
> For now we only allow Dom0 to make these calls as they are all managing
> hardware. There is no specification for these SIP calls, the IDs and names
> have been extracted from the upstream linux kernel and the vendor kernel.
> 
> Most of the SIP calls are only available for the iMX8M series of SoCs, so
> they are easy to reject and they need to be revisited when iMX8M series
> support is added.
I just realized that you pinged me in v2 for clarification, sorry I missed that.
I still believe we shouldn't list FIDs that are meant for IMX8M, given that
the driver is written for IMX8QM/QXP.

> 
> From the other calls we can reject CPUFREQ because Dom0 cannot make an
> informed decision regarding CPU frequency scaling, WAKEUP_SRC is to wake
> up from suspend, which Xen doesn't support at this time.
> 
> This leaves the TIME SIP, OTP SIPs, BUILDINFO SIP and TEMP ALARM SIP, which
> for now are allowed to Dom0.
> 
> NOTE: This code is based on code found in NXP Xen tree located here:
> https://github.com/nxp-imx/imx-xen/blob/lf-5.10.y_4.13/xen/arch/arm/platforms/imx8qm.c
> 
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> [jernberg: Add SIP call filtering]
> Signed-off-by: John Ernberg <john.ernberg@actia.se>
> 
> ---
> 
> v3:
>  - Adhere to style guidelines for line length and label indentation (Michal Orzel)
>  - Use smccc macros to build the SIP function identifier (Michal Orzel)
>  - Adjust platform name to be specific to QM and QXP variants (Michal Orzel)
>  - Pick up additional SIPs which may be used by other Linux versions - for review purposes
>  - Changes to the commit message due to above
> 
> v2:
>  - Reword the commit message to be a bit clearer
>  - Include the link previously added as a context note to the commit message (Julien Grall)
>  - Add Pengs signed off (Julien Grall, Peng Fan)
>  - Add basic SIP call filter (Julien Grall)
>  - Expand the commit message a whole bunch because of the changes to the code
> ---
>  xen/arch/arm/platforms/Makefile |   1 +
>  xen/arch/arm/platforms/imx8qm.c | 168 ++++++++++++++++++++++++++++++++
>  2 files changed, 169 insertions(+)
>  create mode 100644 xen/arch/arm/platforms/imx8qm.c
> 
> diff --git a/xen/arch/arm/platforms/Makefile b/xen/arch/arm/platforms/Makefile
> index 8632f4115f..bec6e55d1f 100644
> --- a/xen/arch/arm/platforms/Makefile
> +++ b/xen/arch/arm/platforms/Makefile
> @@ -9,5 +9,6 @@ obj-$(CONFIG_ALL_PLAT)   += sunxi.o
>  obj-$(CONFIG_ALL64_PLAT) += thunderx.o
>  obj-$(CONFIG_ALL64_PLAT) += xgene-storm.o
>  obj-$(CONFIG_ALL64_PLAT) += brcm-raspberry-pi.o
> +obj-$(CONFIG_ALL64_PLAT) += imx8qm.o
>  obj-$(CONFIG_MPSOC_PLATFORM)  += xilinx-zynqmp.o
>  obj-$(CONFIG_MPSOC_PLATFORM)  += xilinx-zynqmp-eemi.o
> diff --git a/xen/arch/arm/platforms/imx8qm.c b/xen/arch/arm/platforms/imx8qm.c
> new file mode 100644
> index 0000000000..0992475474
> --- /dev/null
> +++ b/xen/arch/arm/platforms/imx8qm.c
> @@ -0,0 +1,168 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * xen/arch/arm/platforms/imx8qm.c
> + *
> + * i.MX 8QM setup
> + *
> + * Copyright (c) 2016 Freescale Inc.
> + * Copyright 2018-2019 NXP
> + *
> + *
> + * Peng Fan <peng.fan@nxp.com>
> + */
> +
> +#include <xen/sched.h>
> +#include <asm/platform.h>
> +#include <asm/smccc.h>
> +
> +static const char * const imx8qm_dt_compat[] __initconst =
> +{
> +    "fsl,imx8qm",
> +    "fsl,imx8qxp",
> +    NULL
> +};
> +
> +#define IMX_SIP_FID(fid) \
> +    ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
> +                       ARM_SMCCC_CONV_64, \
> +                       ARM_SMCCC_OWNER_SIP, \
> +                       fid)
macro parameter should be enclosed within parenthesis

> +
> +#define IMX_SIP_F_GPC            0x0000
> +#define IMX_SIP_F_CPUFREQ        0x0001
> +#define IMX_SIP_F_TIME           0x0002
> +#define IMX_SIP_F_BUILDINFO      0x0003
> +#define IMX_SIP_F_DDR_DVFS       0x0004
> +#define IMX_SIP_F_SRC            0x0005
> +#define IMX_SIP_F_GET_SOC_INFO   0x0006
> +#define IMX_SIP_F_NOC            0x0008
> +#define IMX_SIP_F_WAKEUP_SRC     0x0009
> +#define IMX_SIP_F_OTP_READ       0x000A
> +#define IMX_SIP_F_OTP_WRITE      0x000B
> +#define IMX_SIP_F_SET_TEMP_ALARM 0x000C
Is there specific reason for leading zeros?

> +
> +#define IMX_SIP_TIME_SF_RTC_SET_TIME     0x00
> +#define IMX_SIP_TIME_SF_WDOG_START       0x01
> +#define IMX_SIP_TIME_SF_WDOG_STOP        0x02
> +#define IMX_SIP_TIME_SF_WDOG_SET_ACT     0x03
> +#define IMX_SIP_TIME_SF_WDOG_PING        0x04
> +#define IMX_SIP_TIME_SF_WDOG_SET_TIMEOUT 0x05
> +#define IMX_SIP_TIME_SF_WDOG_GET_STAT    0x06
> +#define IMX_SIP_TIME_SF_WDOG_SET_PRETIME 0x07
> +
> +static bool imx8qm_is_sip_time_call_ok(uint32_t subfunction_id)
> +{
> +    switch ( subfunction_id )
> +    {
> +    case IMX_SIP_TIME_SF_RTC_SET_TIME:
> +        return true;
> +    case IMX_SIP_TIME_SF_WDOG_START:
> +    case IMX_SIP_TIME_SF_WDOG_STOP:
> +    case IMX_SIP_TIME_SF_WDOG_SET_ACT:
> +    case IMX_SIP_TIME_SF_WDOG_PING:
> +    case IMX_SIP_TIME_SF_WDOG_SET_TIMEOUT:
> +    case IMX_SIP_TIME_SF_WDOG_GET_STAT:
> +    case IMX_SIP_TIME_SF_WDOG_SET_PRETIME:
> +        return true;
> +    default:
> +        printk(XENLOG_WARNING "imx8qm: smc: time: Unknown subfunction id %x\n",
gprintk

> +               subfunction_id);
> +        return false;
> +    }
> +}
> +
> +static bool imx8qm_smc(struct cpu_user_regs *regs)
> +{
> +    uint32_t function_id = get_user_reg(regs, 0);
> +    uint32_t subfunction_id = get_user_reg(regs, 1);
> +    struct arm_smccc_res res;
> +
> +    if ( !cpus_have_const_cap(ARM_SMCCC_1_1) )
> +    {
> +        printk_once(XENLOG_WARNING "no SMCCC 1.1 support. Disabling firmware calls\n");
NIT: you can move string within quotes to the next line to avoid exceeding 80 chars.
Also, all the other messages are prepended with "imx8qm: smc:" so better be consistent.

> +
> +        return false;
> +    }
> +
> +    /* Only hardware domain may use the SIP calls */
> +    if ( !is_hardware_domain(current->domain) )
> +    {
> +        gprintk(XENLOG_WARNING, "imx8qm: smc: No access\n");
Here you use gprintk, but ...

> +        return false;
> +    }
> +
> +    switch ( function_id )
> +    {
> +    /* Only available on imx8m series */
> +    case IMX_SIP_FID(IMX_SIP_F_GPC):
> +        return false;
> +    case IMX_SIP_FID(IMX_SIP_F_CPUFREQ):
> +        /* Hardware domain can't take any informed decision here */
> +        return false;
> +    case IMX_SIP_FID(IMX_SIP_F_BUILDINFO):
> +        goto allow_call;
> +    case IMX_SIP_FID(IMX_SIP_F_TIME):
> +        if ( imx8qm_is_sip_time_call_ok(subfunction_id) )
> +            goto allow_call;
> +        return false;
> +    /* Only available on imx8m series */
> +    case IMX_SIP_FID(IMX_SIP_F_DDR_DVFS):
> +        return false;
> +    /* Only available on imx8m series */
> +    case IMX_SIP_FID(IMX_SIP_F_SRC):
> +        return false;
> +    /* Only available on imx8m series */
> +    case IMX_SIP_FID(IMX_SIP_F_GET_SOC_INFO):
> +        return false;
> +    /* Only available on imx8m series */
> +    case IMX_SIP_FID(IMX_SIP_F_NOC):
> +        return false;
> +    /* Xen doesn't have suspend support */
> +    case IMX_SIP_FID(IMX_SIP_F_WAKEUP_SRC):
> +        return false;
> +    case IMX_SIP_FID(IMX_SIP_F_OTP_READ):
> +        /* subfunction_id is the fuse number, no sensible check possible */
> +        goto allow_call;
> +    case IMX_SIP_FID(IMX_SIP_F_OTP_WRITE):
> +        /* subfunction_id is the fuse number, no sensible check possible */
> +        goto allow_call;
> +    case IMX_SIP_FID(IMX_SIP_F_SET_TEMP_ALARM):
> +        goto allow_call;
> +    default:
> +        printk(XENLOG_WARNING "imx8qm: smc: Unknown function id %x\n",
... here you don't.

> +               function_id);
> +        return false;
> +    }
> +
> + allow_call:
> +    arm_smccc_1_1_smc(function_id,
> +                      subfunction_id,
> +                      get_user_reg(regs, 2),
> +                      get_user_reg(regs, 3),
> +                      get_user_reg(regs, 4),
> +                      get_user_reg(regs, 5),
> +                      get_user_reg(regs, 6),
> +                      get_user_reg(regs, 7),
> +                      &res);
> +
> +    set_user_reg(regs, 0, res.a0);
> +    set_user_reg(regs, 1, res.a1);
> +    set_user_reg(regs, 2, res.a2);
> +    set_user_reg(regs, 3, res.a3);
> +
> +    return true;
> +}
> +
> +PLATFORM_START(imx8qm, "i.MX 8Q{M,XP}")
> +    .compatible = imx8qm_dt_compat,
> +    .smc = imx8qm_smc,
> +PLATFORM_END
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> --
> 2.44.0


~Michal
John Ernberg April 8, 2024, 7:13 a.m. UTC | #2
Hi Michel,

Apologies for the slow reply.

On 4/2/24 9:24 AM, Michal Orzel wrote:
> Hi John,
> 
> On 28/03/2024 17:34, John Ernberg wrote:
>>
>>
>> When using Linux for dom0 there are a bunch of drivers that need to do SMC
>> SIP calls into the firmware to enable certain hardware bits like the
>> watchdog.
>>
>> Provide a basic platform glue that implements the needed SMC forwarding.
>>
>> The format of these calls are as follows:
>>   - reg 0: function ID
>>   - reg 1: subfunction ID (when there's a subfunction)
>>   remaining regs: args
>>
>> For now we only allow Dom0 to make these calls as they are all managing
>> hardware. There is no specification for these SIP calls, the IDs and names
>> have been extracted from the upstream linux kernel and the vendor kernel.
>>
>> Most of the SIP calls are only available for the iMX8M series of SoCs, so
>> they are easy to reject and they need to be revisited when iMX8M series
>> support is added.
> I just realized that you pinged me in v2 for clarification, sorry I missed that.
> I still believe we shouldn't list FIDs that are meant for IMX8M, given that
> the driver is written for IMX8QM/QXP.

Ack. Will take them all out and only add the known required set.

> 
>>
>>  From the other calls we can reject CPUFREQ because Dom0 cannot make an
>> informed decision regarding CPU frequency scaling, WAKEUP_SRC is to wake
>> up from suspend, which Xen doesn't support at this time.
>>
>> This leaves the TIME SIP, OTP SIPs, BUILDINFO SIP and TEMP ALARM SIP, which
>> for now are allowed to Dom0.
>>
>> NOTE: This code is based on code found in NXP Xen tree located here:
>> https://github.com/nxp-imx/imx-xen/blob/lf-5.10.y_4.13/xen/arch/arm/platforms/imx8qm.c
>>
>> Signed-off-by: Peng Fan <peng.fan@nxp.com>
>> [jernberg: Add SIP call filtering]
>> Signed-off-by: John Ernberg <john.ernberg@actia.se>
>>
>> ---
>>
>> v3:
>>   - Adhere to style guidelines for line length and label indentation (Michal Orzel)
>>   - Use smccc macros to build the SIP function identifier (Michal Orzel)
>>   - Adjust platform name to be specific to QM and QXP variants (Michal Orzel)
>>   - Pick up additional SIPs which may be used by other Linux versions - for review purposes
>>   - Changes to the commit message due to above
>>
>> v2:
>>   - Reword the commit message to be a bit clearer
>>   - Include the link previously added as a context note to the commit message (Julien Grall)
>>   - Add Pengs signed off (Julien Grall, Peng Fan)
>>   - Add basic SIP call filter (Julien Grall)
>>   - Expand the commit message a whole bunch because of the changes to the code
>> ---
>>   xen/arch/arm/platforms/Makefile |   1 +
>>   xen/arch/arm/platforms/imx8qm.c | 168 ++++++++++++++++++++++++++++++++
>>   2 files changed, 169 insertions(+)
>>   create mode 100644 xen/arch/arm/platforms/imx8qm.c
>>
>> diff --git a/xen/arch/arm/platforms/Makefile b/xen/arch/arm/platforms/Makefile
>> index 8632f4115f..bec6e55d1f 100644
>> --- a/xen/arch/arm/platforms/Makefile
>> +++ b/xen/arch/arm/platforms/Makefile
>> @@ -9,5 +9,6 @@ obj-$(CONFIG_ALL_PLAT)   += sunxi.o
>>   obj-$(CONFIG_ALL64_PLAT) += thunderx.o
>>   obj-$(CONFIG_ALL64_PLAT) += xgene-storm.o
>>   obj-$(CONFIG_ALL64_PLAT) += brcm-raspberry-pi.o
>> +obj-$(CONFIG_ALL64_PLAT) += imx8qm.o
>>   obj-$(CONFIG_MPSOC_PLATFORM)  += xilinx-zynqmp.o
>>   obj-$(CONFIG_MPSOC_PLATFORM)  += xilinx-zynqmp-eemi.o
>> diff --git a/xen/arch/arm/platforms/imx8qm.c b/xen/arch/arm/platforms/imx8qm.c
>> new file mode 100644
>> index 0000000000..0992475474
>> --- /dev/null
>> +++ b/xen/arch/arm/platforms/imx8qm.c
>> @@ -0,0 +1,168 @@
>> +/* SPDX-License-Identifier: GPL-2.0-or-later */
>> +/*
>> + * xen/arch/arm/platforms/imx8qm.c
>> + *
>> + * i.MX 8QM setup
>> + *
>> + * Copyright (c) 2016 Freescale Inc.
>> + * Copyright 2018-2019 NXP
>> + *
>> + *
>> + * Peng Fan <peng.fan@nxp.com>
>> + */
>> +
>> +#include <xen/sched.h>
>> +#include <asm/platform.h>
>> +#include <asm/smccc.h>
>> +
>> +static const char * const imx8qm_dt_compat[] __initconst =
>> +{
>> +    "fsl,imx8qm",
>> +    "fsl,imx8qxp",
>> +    NULL
>> +};
>> +
>> +#define IMX_SIP_FID(fid) \
>> +    ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
>> +                       ARM_SMCCC_CONV_64, \
>> +                       ARM_SMCCC_OWNER_SIP, \
>> +                       fid)
> macro parameter should be enclosed within parenthesis

Ack.
> 
>> +
>> +#define IMX_SIP_F_GPC            0x0000
>> +#define IMX_SIP_F_CPUFREQ        0x0001
>> +#define IMX_SIP_F_TIME           0x0002
>> +#define IMX_SIP_F_BUILDINFO      0x0003
>> +#define IMX_SIP_F_DDR_DVFS       0x0004
>> +#define IMX_SIP_F_SRC            0x0005
>> +#define IMX_SIP_F_GET_SOC_INFO   0x0006
>> +#define IMX_SIP_F_NOC            0x0008
>> +#define IMX_SIP_F_WAKEUP_SRC     0x0009
>> +#define IMX_SIP_F_OTP_READ       0x000A
>> +#define IMX_SIP_F_OTP_WRITE      0x000B
>> +#define IMX_SIP_F_SET_TEMP_ALARM 0x000C
> Is there specific reason for leading zeros?

Nope. I'll drop them.
> 
>> +
>> +#define IMX_SIP_TIME_SF_RTC_SET_TIME     0x00
>> +#define IMX_SIP_TIME_SF_WDOG_START       0x01
>> +#define IMX_SIP_TIME_SF_WDOG_STOP        0x02
>> +#define IMX_SIP_TIME_SF_WDOG_SET_ACT     0x03
>> +#define IMX_SIP_TIME_SF_WDOG_PING        0x04
>> +#define IMX_SIP_TIME_SF_WDOG_SET_TIMEOUT 0x05
>> +#define IMX_SIP_TIME_SF_WDOG_GET_STAT    0x06
>> +#define IMX_SIP_TIME_SF_WDOG_SET_PRETIME 0x07
>> +
>> +static bool imx8qm_is_sip_time_call_ok(uint32_t subfunction_id)
>> +{
>> +    switch ( subfunction_id )
>> +    {
>> +    case IMX_SIP_TIME_SF_RTC_SET_TIME:
>> +        return true;
>> +    case IMX_SIP_TIME_SF_WDOG_START:
>> +    case IMX_SIP_TIME_SF_WDOG_STOP:
>> +    case IMX_SIP_TIME_SF_WDOG_SET_ACT:
>> +    case IMX_SIP_TIME_SF_WDOG_PING:
>> +    case IMX_SIP_TIME_SF_WDOG_SET_TIMEOUT:
>> +    case IMX_SIP_TIME_SF_WDOG_GET_STAT:
>> +    case IMX_SIP_TIME_SF_WDOG_SET_PRETIME:
>> +        return true;
>> +    default:
>> +        printk(XENLOG_WARNING "imx8qm: smc: time: Unknown subfunction id %x\n",
> gprintk

Ack.
> 
>> +               subfunction_id);
>> +        return false;
>> +    }
>> +}
>> +
>> +static bool imx8qm_smc(struct cpu_user_regs *regs)
>> +{
>> +    uint32_t function_id = get_user_reg(regs, 0);
>> +    uint32_t subfunction_id = get_user_reg(regs, 1);
>> +    struct arm_smccc_res res;
>> +
>> +    if ( !cpus_have_const_cap(ARM_SMCCC_1_1) )
>> +    {
>> +        printk_once(XENLOG_WARNING "no SMCCC 1.1 support. Disabling firmware calls\n");
> NIT: you can move string within quotes to the next line to avoid exceeding 80 chars.
> Also, all the other messages are prepended with "imx8qm: smc:" so better be consistent.

Ack.
> 
>> +
>> +        return false;
>> +    }
>> +
>> +    /* Only hardware domain may use the SIP calls */
>> +    if ( !is_hardware_domain(current->domain) )
>> +    {
>> +        gprintk(XENLOG_WARNING, "imx8qm: smc: No access\n");
> Here you use gprintk, but ...
> 
>> +        return false;
>> +    }
>> +
>> +    switch ( function_id )
>> +    {
>> +    /* Only available on imx8m series */
>> +    case IMX_SIP_FID(IMX_SIP_F_GPC):
>> +        return false;
>> +    case IMX_SIP_FID(IMX_SIP_F_CPUFREQ):
>> +        /* Hardware domain can't take any informed decision here */
>> +        return false;
>> +    case IMX_SIP_FID(IMX_SIP_F_BUILDINFO):
>> +        goto allow_call;
>> +    case IMX_SIP_FID(IMX_SIP_F_TIME):
>> +        if ( imx8qm_is_sip_time_call_ok(subfunction_id) )
>> +            goto allow_call;
>> +        return false;
>> +    /* Only available on imx8m series */
>> +    case IMX_SIP_FID(IMX_SIP_F_DDR_DVFS):
>> +        return false;
>> +    /* Only available on imx8m series */
>> +    case IMX_SIP_FID(IMX_SIP_F_SRC):
>> +        return false;
>> +    /* Only available on imx8m series */
>> +    case IMX_SIP_FID(IMX_SIP_F_GET_SOC_INFO):
>> +        return false;
>> +    /* Only available on imx8m series */
>> +    case IMX_SIP_FID(IMX_SIP_F_NOC):
>> +        return false;
>> +    /* Xen doesn't have suspend support */
>> +    case IMX_SIP_FID(IMX_SIP_F_WAKEUP_SRC):
>> +        return false;
>> +    case IMX_SIP_FID(IMX_SIP_F_OTP_READ):
>> +        /* subfunction_id is the fuse number, no sensible check possible */
>> +        goto allow_call;
>> +    case IMX_SIP_FID(IMX_SIP_F_OTP_WRITE):
>> +        /* subfunction_id is the fuse number, no sensible check possible */
>> +        goto allow_call;
>> +    case IMX_SIP_FID(IMX_SIP_F_SET_TEMP_ALARM):
>> +        goto allow_call;
>> +    default:
>> +        printk(XENLOG_WARNING "imx8qm: smc: Unknown function id %x\n",
> ... here you don't.

Still getting used gprintk.
> 
>> +               function_id);
>> +        return false;
>> +    }
>> +
>> + allow_call:
>> +    arm_smccc_1_1_smc(function_id,
>> +                      subfunction_id,
>> +                      get_user_reg(regs, 2),
>> +                      get_user_reg(regs, 3),
>> +                      get_user_reg(regs, 4),
>> +                      get_user_reg(regs, 5),
>> +                      get_user_reg(regs, 6),
>> +                      get_user_reg(regs, 7),
>> +                      &res);
>> +
>> +    set_user_reg(regs, 0, res.a0);
>> +    set_user_reg(regs, 1, res.a1);
>> +    set_user_reg(regs, 2, res.a2);
>> +    set_user_reg(regs, 3, res.a3);
>> +
>> +    return true;
>> +}
>> +
>> +PLATFORM_START(imx8qm, "i.MX 8Q{M,XP}")
>> +    .compatible = imx8qm_dt_compat,
>> +    .smc = imx8qm_smc,
>> +PLATFORM_END
>> +
>> +/*
>> + * Local variables:
>> + * mode: C
>> + * c-file-style: "BSD"
>> + * c-basic-offset: 4
>> + * indent-tabs-mode: nil
>> + * End:
>> + */
>> --
>> 2.44.0
> 
> 
> ~Michal

Thanks! // John Ernberg
diff mbox series

Patch

diff --git a/xen/arch/arm/platforms/Makefile b/xen/arch/arm/platforms/Makefile
index 8632f4115f..bec6e55d1f 100644
--- a/xen/arch/arm/platforms/Makefile
+++ b/xen/arch/arm/platforms/Makefile
@@ -9,5 +9,6 @@  obj-$(CONFIG_ALL_PLAT)   += sunxi.o
 obj-$(CONFIG_ALL64_PLAT) += thunderx.o
 obj-$(CONFIG_ALL64_PLAT) += xgene-storm.o
 obj-$(CONFIG_ALL64_PLAT) += brcm-raspberry-pi.o
+obj-$(CONFIG_ALL64_PLAT) += imx8qm.o
 obj-$(CONFIG_MPSOC_PLATFORM)  += xilinx-zynqmp.o
 obj-$(CONFIG_MPSOC_PLATFORM)  += xilinx-zynqmp-eemi.o
diff --git a/xen/arch/arm/platforms/imx8qm.c b/xen/arch/arm/platforms/imx8qm.c
new file mode 100644
index 0000000000..0992475474
--- /dev/null
+++ b/xen/arch/arm/platforms/imx8qm.c
@@ -0,0 +1,168 @@ 
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * xen/arch/arm/platforms/imx8qm.c
+ *
+ * i.MX 8QM setup
+ *
+ * Copyright (c) 2016 Freescale Inc.
+ * Copyright 2018-2019 NXP
+ *
+ *
+ * Peng Fan <peng.fan@nxp.com>
+ */
+
+#include <xen/sched.h>
+#include <asm/platform.h>
+#include <asm/smccc.h>
+
+static const char * const imx8qm_dt_compat[] __initconst =
+{
+    "fsl,imx8qm",
+    "fsl,imx8qxp",
+    NULL
+};
+
+#define IMX_SIP_FID(fid) \
+    ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
+                       ARM_SMCCC_CONV_64, \
+                       ARM_SMCCC_OWNER_SIP, \
+                       fid)
+
+#define IMX_SIP_F_GPC            0x0000
+#define IMX_SIP_F_CPUFREQ        0x0001
+#define IMX_SIP_F_TIME           0x0002
+#define IMX_SIP_F_BUILDINFO      0x0003
+#define IMX_SIP_F_DDR_DVFS       0x0004
+#define IMX_SIP_F_SRC            0x0005
+#define IMX_SIP_F_GET_SOC_INFO   0x0006
+#define IMX_SIP_F_NOC            0x0008
+#define IMX_SIP_F_WAKEUP_SRC     0x0009
+#define IMX_SIP_F_OTP_READ       0x000A
+#define IMX_SIP_F_OTP_WRITE      0x000B
+#define IMX_SIP_F_SET_TEMP_ALARM 0x000C
+
+#define IMX_SIP_TIME_SF_RTC_SET_TIME     0x00
+#define IMX_SIP_TIME_SF_WDOG_START       0x01
+#define IMX_SIP_TIME_SF_WDOG_STOP        0x02
+#define IMX_SIP_TIME_SF_WDOG_SET_ACT     0x03
+#define IMX_SIP_TIME_SF_WDOG_PING        0x04
+#define IMX_SIP_TIME_SF_WDOG_SET_TIMEOUT 0x05
+#define IMX_SIP_TIME_SF_WDOG_GET_STAT    0x06
+#define IMX_SIP_TIME_SF_WDOG_SET_PRETIME 0x07
+
+static bool imx8qm_is_sip_time_call_ok(uint32_t subfunction_id)
+{
+    switch ( subfunction_id )
+    {
+    case IMX_SIP_TIME_SF_RTC_SET_TIME:
+        return true;
+    case IMX_SIP_TIME_SF_WDOG_START:
+    case IMX_SIP_TIME_SF_WDOG_STOP:
+    case IMX_SIP_TIME_SF_WDOG_SET_ACT:
+    case IMX_SIP_TIME_SF_WDOG_PING:
+    case IMX_SIP_TIME_SF_WDOG_SET_TIMEOUT:
+    case IMX_SIP_TIME_SF_WDOG_GET_STAT:
+    case IMX_SIP_TIME_SF_WDOG_SET_PRETIME:
+        return true;
+    default:
+        printk(XENLOG_WARNING "imx8qm: smc: time: Unknown subfunction id %x\n",
+               subfunction_id);
+        return false;
+    }
+}
+
+static bool imx8qm_smc(struct cpu_user_regs *regs)
+{
+    uint32_t function_id = get_user_reg(regs, 0);
+    uint32_t subfunction_id = get_user_reg(regs, 1);
+    struct arm_smccc_res res;
+
+    if ( !cpus_have_const_cap(ARM_SMCCC_1_1) )
+    {
+        printk_once(XENLOG_WARNING "no SMCCC 1.1 support. Disabling firmware calls\n");
+
+        return false;
+    }
+
+    /* Only hardware domain may use the SIP calls */
+    if ( !is_hardware_domain(current->domain) )
+    {
+        gprintk(XENLOG_WARNING, "imx8qm: smc: No access\n");
+        return false;
+    }
+
+    switch ( function_id )
+    {
+    /* Only available on imx8m series */
+    case IMX_SIP_FID(IMX_SIP_F_GPC):
+        return false;
+    case IMX_SIP_FID(IMX_SIP_F_CPUFREQ):
+        /* Hardware domain can't take any informed decision here */
+        return false;
+    case IMX_SIP_FID(IMX_SIP_F_BUILDINFO):
+        goto allow_call;
+    case IMX_SIP_FID(IMX_SIP_F_TIME):
+        if ( imx8qm_is_sip_time_call_ok(subfunction_id) )
+            goto allow_call;
+        return false;
+    /* Only available on imx8m series */
+    case IMX_SIP_FID(IMX_SIP_F_DDR_DVFS):
+        return false;
+    /* Only available on imx8m series */
+    case IMX_SIP_FID(IMX_SIP_F_SRC):
+        return false;
+    /* Only available on imx8m series */
+    case IMX_SIP_FID(IMX_SIP_F_GET_SOC_INFO):
+        return false;
+    /* Only available on imx8m series */
+    case IMX_SIP_FID(IMX_SIP_F_NOC):
+        return false;
+    /* Xen doesn't have suspend support */
+    case IMX_SIP_FID(IMX_SIP_F_WAKEUP_SRC):
+        return false;
+    case IMX_SIP_FID(IMX_SIP_F_OTP_READ):
+        /* subfunction_id is the fuse number, no sensible check possible */
+        goto allow_call;
+    case IMX_SIP_FID(IMX_SIP_F_OTP_WRITE):
+        /* subfunction_id is the fuse number, no sensible check possible */
+        goto allow_call;
+    case IMX_SIP_FID(IMX_SIP_F_SET_TEMP_ALARM):
+        goto allow_call;
+    default:
+        printk(XENLOG_WARNING "imx8qm: smc: Unknown function id %x\n",
+               function_id);
+        return false;
+    }
+
+ allow_call:
+    arm_smccc_1_1_smc(function_id,
+                      subfunction_id,
+                      get_user_reg(regs, 2),
+                      get_user_reg(regs, 3),
+                      get_user_reg(regs, 4),
+                      get_user_reg(regs, 5),
+                      get_user_reg(regs, 6),
+                      get_user_reg(regs, 7),
+                      &res);
+
+    set_user_reg(regs, 0, res.a0);
+    set_user_reg(regs, 1, res.a1);
+    set_user_reg(regs, 2, res.a2);
+    set_user_reg(regs, 3, res.a3);
+
+    return true;
+}
+
+PLATFORM_START(imx8qm, "i.MX 8Q{M,XP}")
+    .compatible = imx8qm_dt_compat,
+    .smc = imx8qm_smc,
+PLATFORM_END
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */