Skip to contentSkip to conversation

firmware: qcom: scm: Split out 32-bit specific SCM code

PATCH In review Kumar Gala 4 participants 8 messages Apr 28, 2015 – Aug 6, 2015

Subsystems (2)
lore
Share & tools
lore

Kumar Gala

author
#0 lore raw

PATCH v5 1/2 firmware: qcom: scm: Split out 32-bit specific SCM code

Split out the 32-bit SCM implementation into its own file to prep for supporting a 64-bit/ARM64 implementation as well. We create a simple shim to ensure both versions conform to the same interface.

---
v5:
Split out error defines in common qcom_scm.h

 drivers/firmware/Makefile                      |   3 +-
 drivers/firmware/{qcom_scm.c => qcom_scm-32.c} |  22 +-
 drivers/firmware/qcom_scm.c                    | 442 +------------------------
 drivers/firmware/qcom_scm.h                    |  38 +++
 4 files changed, 51 insertions(+), 454 deletions(-)
 copy drivers/firmware/{qcom_scm.c => qcom_scm-32.c} (95%)
 create mode 100644 drivers/firmware/qcom_scm.h
drivers/firmware/Makefile +2 -1
index 3fdd391..3001f1a 100644
@@ -12,7 +12,8 @@ obj-$(CONFIG_ISCSI_IBFT_FIND)	+= iscsi_ibft_find.o
 obj-$(CONFIG_ISCSI_IBFT)	+= iscsi_ibft.o
 obj-$(CONFIG_FIRMWARE_MEMMAP)	+= memmap.o
 obj-$(CONFIG_QCOM_SCM)		+= qcom_scm.o
-CFLAGS_qcom_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
+obj-$(CONFIG_QCOM_SCM)		+= qcom_scm-32.o
+CFLAGS_qcom_scm-32.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
 
 obj-$(CONFIG_GOOGLE_FIRMWARE)	+= google/
 obj-$(CONFIG_EFI)		+= efi/
drivers/firmware/qcom_scm-32.c renamed from drivers/firmware/qcom_scm.c +4 -18
similarity index 95%
copy from drivers/firmware/qcom_scm.c
copy to drivers/firmware/qcom_scm-32.c
index 994b50f..b08b822 100644
@@ -27,13 +27,7 @@
 #include <asm/outercache.h>
 #include <asm/cacheflush.h>
 
-
-#define QCOM_SCM_ENOMEM		-5
-#define QCOM_SCM_EOPNOTSUPP	-4
-#define QCOM_SCM_EINVAL_ADDR	-3
-#define QCOM_SCM_EINVAL_ARG	-2
-#define QCOM_SCM_ERROR		-1
-#define QCOM_SCM_INTERRUPTED	1
+#include "qcom_scm.h"
 
 #define QCOM_SCM_FLAG_COLDBOOT_CPU0	0x00
 #define QCOM_SCM_FLAG_COLDBOOT_CPU1	0x01
@@ -386,8 +380,6 @@ u32 qcom_scm_get_version(void)
 }
 EXPORT_SYMBOL(qcom_scm_get_version);
 
-#define QCOM_SCM_SVC_BOOT			0x1
-#define QCOM_SCM_BOOT_ADDR			0x1
 /*
  * Set the cold/warm boot address for one of the CPU cores.
  */
@@ -412,7 +404,7 @@ static int qcom_scm_set_boot_addr(u32 addr, int flags)
  * Set the cold boot address of the cpus. Any cpu outside the supported
  * range would be removed from the cpu present mask.
  */
-int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
+int __qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
 {
 	int flags = 0;
 	int cpu;
@@ -435,7 +427,6 @@ int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
 
 	return qcom_scm_set_boot_addr(virt_to_phys(entry), flags);
 }
-EXPORT_SYMBOL(qcom_scm_set_cold_boot_addr);
 
 /**
  * qcom_scm_set_warm_boot_addr() - Set the warm boot address for cpus
@@ -445,7 +436,7 @@ EXPORT_SYMBOL(qcom_scm_set_cold_boot_addr);
  * Set the Linux entry point for the SCM to transfer control to when coming
  * out of a power down. CPU power down may be executed on cpuidle or hotplug.
  */
-int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus)
+int __qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus)
 {
 	int ret;
 	int flags = 0;
@@ -473,10 +464,6 @@ int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus)
 
 	return ret;
 }
-EXPORT_SYMBOL(qcom_scm_set_warm_boot_addr);
-
-#define QCOM_SCM_CMD_TERMINATE_PC	0x2
-#define QCOM_SCM_FLUSH_FLAG_MASK	0x3
 
 /**
  * qcom_scm_cpu_power_down() - Power down the cpu
@@ -486,9 +473,8 @@ EXPORT_SYMBOL(qcom_scm_set_warm_boot_addr);
  * the control would return from this function, otherwise, the cpu jumps to the
  * warm boot entry point set for this cpu upon reset.
  */
-void qcom_scm_cpu_power_down(u32 flags)
+void __qcom_scm_cpu_power_down(u32 flags)
 {
 	qcom_scm_call_atomic1(QCOM_SCM_SVC_BOOT, QCOM_SCM_CMD_TERMINATE_PC,
 			flags & QCOM_SCM_FLUSH_FLAG_MASK);
 }
-EXPORT_SYMBOL(qcom_scm_cpu_power_down);
drivers/firmware/qcom_scm.c +7 -435

470 lines not on this page · raw message

drivers/firmware/qcom_scm.h new file +38 -0
new file mode 100644
index 0000000..1172be9
@@ -0,0 +1,38 @@
+/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+#ifndef __QCOM_SCM_INT_H
+#define __QCOM_SCM_INT_H
+
+#define QCOM_SCM_SVC_BOOT		0x1
+#define QCOM_SCM_BOOT_ADDR		0x1
+#define QCOM_SCM_BOOT_ADDR_MC		0x11
+
+#define QCOM_SCM_FLAG_HLOS		0x01
+#define QCOM_SCM_FLAG_COLDBOOT_MC	0x02
+#define QCOM_SCM_FLAG_WARMBOOT_MC	0x04
+extern int __qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus);
+extern int __qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus);
+
+#define QCOM_SCM_CMD_TERMINATE_PC	0x2
+#define QCOM_SCM_FLUSH_FLAG_MASK	0x3
+#define QCOM_SCM_CMD_CORE_HOTPLUGGED	0x10
+extern void __qcom_scm_cpu_power_down(u32 flags);
+
+/* common error codes */
+#define QCOM_SCM_ENOMEM		-5
+#define QCOM_SCM_EOPNOTSUPP	-4
+#define QCOM_SCM_EINVAL_ADDR	-3
+#define QCOM_SCM_EINVAL_ARG	-2
+#define QCOM_SCM_ERROR		-1
+#define QCOM_SCM_INTERRUPTED	1
+
+#endif
Signature · 3 lines
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
author
#1 lore raw

PATCH v5 2/2 firmware: qcom: scm: Add support for ARM64 SoCs

Add an implementation of the SCM interface that works on ARM64/64-bit SoCs

---
* v5:
- use common error defines from qcom_scm.h
- removed R*_STR defines

* v4:
- Folded in change to qcom_scm_cpu_power_down to remove HOTPLUG flag from Lina.

 arch/arm64/Kconfig             |   1 +
 drivers/firmware/Makefile      |   4 +
 drivers/firmware/qcom_scm-64.c | 452 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 457 insertions(+)
 create mode 100644 drivers/firmware/qcom_scm-64.c
arch/arm64/Kconfig +1 -0
index 4269dba..8878800 100644
@@ -190,6 +190,7 @@ config ARCH_MEDIATEK
 config ARCH_QCOM
 	bool "Qualcomm Platforms"
 	select PINCTRL
+	select QCOM_SCM
 	help
 	  This enables support for the ARMv8 based Qualcomm chipsets.
 
drivers/firmware/Makefile +4 -0
index 3001f1a..c79751a 100644
@@ -12,7 +12,11 @@ obj-$(CONFIG_ISCSI_IBFT_FIND)	+= iscsi_ibft_find.o
 obj-$(CONFIG_ISCSI_IBFT)	+= iscsi_ibft.o
 obj-$(CONFIG_FIRMWARE_MEMMAP)	+= memmap.o
 obj-$(CONFIG_QCOM_SCM)		+= qcom_scm.o
+ifdef CONFIG_64BIT
+obj-$(CONFIG_QCOM_SCM)		+= qcom_scm-64.o
+else
 obj-$(CONFIG_QCOM_SCM)		+= qcom_scm-32.o
+endif
 CFLAGS_qcom_scm-32.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
 
 obj-$(CONFIG_GOOGLE_FIRMWARE)	+= google/
drivers/firmware/qcom_scm-64.c new file +452 -0

452 lines not on this page · raw message

Signature · 3 lines
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
reviewer
#2 lore raw

Re: [PATCH v5 2/2] firmware: qcom: scm: Add support for ARM64 SoCs

Hi Kumar,

Quoted 1 line · Kumar Gala

Add an implementation of the SCM interface that works on ARM64/64-bit SoCs

What is the intended use of this on arm64 SoCs?

Given the negative reaction to the SMP bringup [1] code that seems to be the only user, I'm somewhat confused as to why this is being pushed as a non-RFC in the mean time.

Are there other users of this interface code? If so, could you please mention that in the commit message. I'd also ask that you would Cc me on future postings of this series.

[...]

Quoted 37 lines
drivers/firmware/qcom_scm-64.c new file +37 -0
+static int qcom_scm_set_boot_addr(void *entry, const cpumask_t *cpus, int flags)
+{
+       struct qcom_scm_desc desc = {0};
+       unsigned int cpu = cpumask_first(cpus);
+       u64 mpidr_el1 = cpu_logical_map(cpu);
+
+       /* For now we assume only a single cpu is set in the mask */
+       WARN_ON(cpumask_weight(cpus) != 1);
+
+       if (mpidr_el1 & ~MPIDR_HWID_BITMASK) {
+               pr_err("CPU%d:Failed to set boot address\n", cpu);
+               return -ENOSYS;
+       }
+
+       desc.args[0] = virt_to_phys(entry);
+       desc.args[1] = BIT(MPIDR_AFFINITY_LEVEL(mpidr_el1, 0));
+       desc.args[2] = BIT(MPIDR_AFFINITY_LEVEL(mpidr_el1, 1));
+       desc.args[3] = BIT(MPIDR_AFFINITY_LEVEL(mpidr_el1, 2));
+       desc.args[4] = ~0ULL;
+       desc.args[5] = QCOM_SCM_FLAG_HLOS | flags;
+       desc.arginfo = QCOM_SCM_ARGS(6);
+
+       return qcom_scm_call(QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_ADDR_MC, &desc);
+}
+
+int __qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
+{
+       int flags = QCOM_SCM_FLAG_COLDBOOT_MC;
+
+       return qcom_scm_set_boot_addr(entry, cpus, flags);
+}
+
+int __qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus)
+{
+       int flags = QCOM_SCM_FLAG_WARMBOOT_MC;
+
+       return qcom_scm_set_boot_addr(entry, cpus, flags);

drivers/firmware/qcom_scm-64.c line 422

Quoted 10 lines
drivers/firmware/qcom_scm-64.c new file +10 -0
+}
+
+void __qcom_scm_cpu_power_down(u32 flags)
+{
+       struct qcom_scm_desc desc = {0};
+       desc.args[0] = flags & QCOM_SCM_FLUSH_FLAG_MASK;
+       desc.arginfo = QCOM_SCM_ARGS(1);
+
+       qcom_scm_call_atomic(QCOM_SCM_SVC_BOOT, QCOM_SCM_CMD_TERMINATE_PC, &desc);
+}

As mentioned in the other thread, I don't want to see this for arm64, and must NAK this portion.

Thanks,
Mark.

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-April/336534.html

author
#3 lore raw

Re: [PATCH v5 2/2] firmware: qcom: scm: Add support for ARM64 SoCs

Quoted 14 lines · Mark Rutland

Hi Kumar,

Quoted 1 line · Kumar Gala

Add an implementation of the SCM interface that works on ARM64/64-bit SoCs

What is the intended use of this on arm64 SoCs?

Given the negative reaction to the SMP bringup [1] code that seems to be the only user, I'm somewhat confused as to why this is being pushed as a non-RFC in the mean time.

Quoted 5 lines

Are there other users of this interface code? If so, could you please mention that in the commit message. I'd also ask that you would Cc me on future postings of this series.

[?]

The SCM interface is needed for other things like display:

https://patchwork.kernel.org/patch/6198691/

Quoted 43 lines
Quoted 43 lines
drivers/firmware/qcom_scm-64.c new file +42 -0
+static int qcom_scm_set_boot_addr(void *entry, const cpumask_t *cpus, int flags)
+{
+       struct qcom_scm_desc desc = {0};
+       unsigned int cpu = cpumask_first(cpus);
+       u64 mpidr_el1 = cpu_logical_map(cpu);
+
+       /* For now we assume only a single cpu is set in the mask */
+       WARN_ON(cpumask_weight(cpus) != 1);
+
+       if (mpidr_el1 & ~MPIDR_HWID_BITMASK) {
+               pr_err("CPU%d:Failed to set boot address\n", cpu);
+               return -ENOSYS;
+       }
+
+       desc.args[0] = virt_to_phys(entry);
+       desc.args[1] = BIT(MPIDR_AFFINITY_LEVEL(mpidr_el1, 0));
+       desc.args[2] = BIT(MPIDR_AFFINITY_LEVEL(mpidr_el1, 1));
+       desc.args[3] = BIT(MPIDR_AFFINITY_LEVEL(mpidr_el1, 2));
+       desc.args[4] = ~0ULL;
+       desc.args[5] = QCOM_SCM_FLAG_HLOS | flags;
+       desc.arginfo = QCOM_SCM_ARGS(6);
+
+       return qcom_scm_call(QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_ADDR_MC, &desc);
+}
+
+int __qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
+{
+       int flags = QCOM_SCM_FLAG_COLDBOOT_MC;
+
+       return qcom_scm_set_boot_addr(entry, cpus, flags);
+}
+
+int __qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus)
+{
+       int flags = QCOM_SCM_FLAG_WARMBOOT_MC;
+
+       return qcom_scm_set_boot_addr(entry, cpus, flags);
+}
+
+void __qcom_scm_cpu_power_down(u32 flags)
+{
+       struct qcom_scm_desc desc = {0};
Quoted 8 lines

drivers/firmware/qcom_scm-64.c line 422

Quoted 5 lines
drivers/firmware/qcom_scm-64.c new file +5 -0
+       desc.args[0] = flags & QCOM_SCM_FLUSH_FLAG_MASK;
+       desc.arginfo = QCOM_SCM_ARGS(1);
+
+       qcom_scm_call_atomic(QCOM_SCM_SVC_BOOT, QCOM_SCM_CMD_TERMINATE_PC, &desc);
+}

As mentioned in the other thread, I don't want to see this for arm64, and must NAK this portion.

I can have these return an error code, but we want to keep the interface the same between the 32-bit and 64-bit.

- k

Signature · 3 lines
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
reviewer
#4 lore raw

Re: [PATCH v5 2/2] firmware: qcom: scm: Add support for ARM64 SoCs

Quoted 18 lines · Kumar Gala
Quoted 18 lines · Mark Rutland

Hi Kumar,

Quoted 1 line · Kumar Gala

Add an implementation of the SCM interface that works on ARM64/64-bit SoCs

What is the intended use of this on arm64 SoCs?

Given the negative reaction to the SMP bringup [1] code that seems to be the only user, I'm somewhat confused as to why this is being pushed as a non-RFC in the mean time.

Are there other users of this interface code? If so, could you please mention that in the commit message. I'd also ask that you would Cc me on future postings of this series.

Quoted 5 lines
Quoted 1 line

[?]

The SCM interface is needed for other things like display:

https://patchwork.kernel.org/patch/6198691/

Thanks for the link. It would be good if you could mention some users in the commit message.

Quoted 51 lines
Quoted 42 lines
Quoted 42 lines
drivers/firmware/qcom_scm-64.c new file +42 -0
+static int qcom_scm_set_boot_addr(void *entry, const cpumask_t *cpus, int flags)
+{
+       struct qcom_scm_desc desc = {0};
+       unsigned int cpu = cpumask_first(cpus);
+       u64 mpidr_el1 = cpu_logical_map(cpu);
+
+       /* For now we assume only a single cpu is set in the mask */
+       WARN_ON(cpumask_weight(cpus) != 1);
+
+       if (mpidr_el1 & ~MPIDR_HWID_BITMASK) {
+               pr_err("CPU%d:Failed to set boot address\n", cpu);
+               return -ENOSYS;
+       }
+
+       desc.args[0] = virt_to_phys(entry);
+       desc.args[1] = BIT(MPIDR_AFFINITY_LEVEL(mpidr_el1, 0));
+       desc.args[2] = BIT(MPIDR_AFFINITY_LEVEL(mpidr_el1, 1));
+       desc.args[3] = BIT(MPIDR_AFFINITY_LEVEL(mpidr_el1, 2));
+       desc.args[4] = ~0ULL;
+       desc.args[5] = QCOM_SCM_FLAG_HLOS | flags;
+       desc.arginfo = QCOM_SCM_ARGS(6);
+
+       return qcom_scm_call(QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_ADDR_MC, &desc);
+}
+
+int __qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
+{
+       int flags = QCOM_SCM_FLAG_COLDBOOT_MC;
+
+       return qcom_scm_set_boot_addr(entry, cpus, flags);
+}
+
+int __qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus)
+{
+       int flags = QCOM_SCM_FLAG_WARMBOOT_MC;
+
+       return qcom_scm_set_boot_addr(entry, cpus, flags);
+}
+
+void __qcom_scm_cpu_power_down(u32 flags)
+{
+       struct qcom_scm_desc desc = {0};
Quoted 8 lines

drivers/firmware/qcom_scm-64.c line 422

Quoted 5 lines
drivers/firmware/qcom_scm-64.c new file +5 -0
+       desc.args[0] = flags & QCOM_SCM_FLUSH_FLAG_MASK;
+       desc.arginfo = QCOM_SCM_ARGS(1);
+
+       qcom_scm_call_atomic(QCOM_SCM_SVC_BOOT, QCOM_SCM_CMD_TERMINATE_PC, &desc);
+}

As mentioned in the other thread, I don't want to see this for arm64, and must NAK this portion.

Quoted 1 line

I can have these return an error code, but we want to keep the interface the same between the 32-bit and 64-bit.

I don't follow. If nothing calls these on the 64-bit side, then there's no interface they need to be there for.

Thanks,
Mark.

author
#5 lore raw

Re: [PATCH v5 2/2] firmware: qcom: scm: Add support for ARM64 SoCs

Quoted 22 lines · Mark Rutland
Quoted 18 lines · Kumar Gala
Quoted 18 lines · Mark Rutland

Hi Kumar,

Quoted 1 line · Kumar Gala

Add an implementation of the SCM interface that works on ARM64/64-bit SoCs

What is the intended use of this on arm64 SoCs?

Given the negative reaction to the SMP bringup [1] code that seems to be the only user, I'm somewhat confused as to why this is being pushed as a non-RFC in the mean time.

Are there other users of this interface code? If so, could you please mention that in the commit message. I'd also ask that you would Cc me on future postings of this series.

Quoted 8 lines
Quoted 5 lines
Quoted 1 line

[?]

The SCM interface is needed for other things like display:

https://patchwork.kernel.org/patch/6198691/

Thanks for the link. It would be good if you could mention some users in the commit message.

I?ll update the commit message

Quoted 52 lines
Quoted 52 lines
Quoted 51 lines
Quoted 38 lines
drivers/firmware/qcom_scm-64.c new file +37 -0
+static int qcom_scm_set_boot_addr(void *entry, const cpumask_t *cpus, int flags)
+{
+       struct qcom_scm_desc desc = {0};
+       unsigned int cpu = cpumask_first(cpus);
+       u64 mpidr_el1 = cpu_logical_map(cpu);
+
+       /* For now we assume only a single cpu is set in the mask */
+       WARN_ON(cpumask_weight(cpus) != 1);
+
+       if (mpidr_el1 & ~MPIDR_HWID_BITMASK) {
+               pr_err("CPU%d:Failed to set boot address\n", cpu);
+               return -ENOSYS;
+       }
+
+       desc.args[0] = virt_to_phys(entry);
+       desc.args[1] = BIT(MPIDR_AFFINITY_LEVEL(mpidr_el1, 0));
+       desc.args[2] = BIT(MPIDR_AFFINITY_LEVEL(mpidr_el1, 1));
+       desc.args[3] = BIT(MPIDR_AFFINITY_LEVEL(mpidr_el1, 2));
+       desc.args[4] = ~0ULL;
+       desc.args[5] = QCOM_SCM_FLAG_HLOS | flags;
+       desc.arginfo = QCOM_SCM_ARGS(6);
+
+       return qcom_scm_call(QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_ADDR_MC, &desc);
+}
+
+int __qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
+{
+       int flags = QCOM_SCM_FLAG_COLDBOOT_MC;
+
+       return qcom_scm_set_boot_addr(entry, cpus, flags);
+}
+
+int __qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus)
+{
+       int flags = QCOM_SCM_FLAG_WARMBOOT_MC;
+
+       return qcom_scm_set_boot_addr(entry, cpus, flags);

drivers/firmware/qcom_scm-64.c line 422

Quoted 10 lines
drivers/firmware/qcom_scm-64.c new file +10 -0
+}
+
+void __qcom_scm_cpu_power_down(u32 flags)
+{
+       struct qcom_scm_desc desc = {0};
+       desc.args[0] = flags & QCOM_SCM_FLUSH_FLAG_MASK;
+       desc.arginfo = QCOM_SCM_ARGS(1);
+
+       qcom_scm_call_atomic(QCOM_SCM_SVC_BOOT, QCOM_SCM_CMD_TERMINATE_PC, &desc);
+}

As mentioned in the other thread, I don't want to see this for arm64, and must NAK this portion.

Quoted 7 lines
Quoted 1 line

I can have these return an error code, but we want to keep the interface the same between the 32-bit and 64-bit.

I don't follow. If nothing calls these on the 64-bit side, then there's no interface they need to be there for.

Thanks,
Mark.

While nothing may call them, its still easier to try and keep the interface the same between 32 and 64-bit side of things. Its the equivalent of when we have a CONFIG_ option disabled, but still allow things to build.

- k

Signature · 3 lines
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
#6 lore raw

Re: [PATCH v5 2/2] firmware: qcom: scm: Add support for ARM64 SoCs

In reply to Kumar Gala

Review

Quoted 10 lines · Kumar Gala
(quoted diff) +10 -0
+
+int __qcom_scm_call_armv8_64(u64 x0, u64 x1, u64 x2, u64 x3, u64 x4, u64 x5,
+				u64 *ret1, u64 *ret2, u64 *ret3)
+{
+	register u64 r0 asm("r0") = x0;
+	register u64 r1 asm("r1") = x1;
+	register u64 r2 asm("r2") = x2;
+	register u64 r3 asm("r3") = x3;
+	register u64 r4 asm("r4") = x4;
+	register u64 r5 asm("r5") = x5;

This should set x6 to 0.

     register u32 r6 asm("r6") = 0;

for example.

Review

Quoted 13 lines
(quoted diff) +13 -0
+
+	do {
+		asm volatile(
+			__asmeq("%0", "x0")
+			__asmeq("%1", "x1")
+			__asmeq("%2", "x2")
+			__asmeq("%3", "x3")
+			__asmeq("%4", "x0")
+			__asmeq("%5", "x1")
+			__asmeq("%6", "x2")
+			__asmeq("%7", "x3")
+			__asmeq("%8", "x4")
+			__asmeq("%9", "x5")

And then the asmeq thing here for x6.

Review

Quoted 7 lines
(quoted diff) +7 -0
+#ifdef REQUIRES_SEC
+			".arch_extension sec\n"
+#endif
+			"smc	#0\n"
+			: "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3)
+			: "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4),
+			  "r" (r5)

And add x6 as an input here.

Review

Quoted 1 line
(quoted diff) +1 -0
+			: "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13",

and remove x6 as a clobber.

Quoted 12 lines
(quoted diff) +12 -0
+			  "x14", "x15", "x16", "x17");
+	} while (r0 == QCOM_SCM_INTERRUPTED);
+
+	if (ret1)
+		*ret1 = r1;
+	if (ret2)
+		*ret2 = r2;
+	if (ret3)
+		*ret3 = r3;
+
+	return r0;
+}

Review

Quoted 10 lines
(quoted diff) +10 -0
+
+int __qcom_scm_call_armv8_32(u32 w0, u32 w1, u32 w2, u32 w3, u32 w4, u32 w5,
+				u64 *ret1, u64 *ret2, u64 *ret3)
+{
+	register u32 r0 asm("r0") = w0;
+	register u32 r1 asm("r1") = w1;
+	register u32 r2 asm("r2") = w2;
+	register u32 r3 asm("r3") = w3;
+	register u32 r4 asm("r4") = w4;
+	register u32 r5 asm("r5") = w5;

This needs to set r6 to 0 as well

     register u32 r6 asm("r6") = 0;

for example.

Review

Quoted 13 lines
(quoted diff) +13 -0
+
+	do {
+		asm volatile(
+			__asmeq("%0", "x0")
+			__asmeq("%1", "x1")
+			__asmeq("%2", "x2")
+			__asmeq("%3", "x3")
+			__asmeq("%4", "x0")
+			__asmeq("%5", "x1")
+			__asmeq("%6", "x2")
+			__asmeq("%7", "x3")
+			__asmeq("%8", "x4")
+			__asmeq("%9", "x5")

And then another asmeq thing here for x6.

Review

Quoted 7 lines
(quoted diff) +7 -0
+#ifdef REQUIRES_SEC
+			".arch_extension sec\n"
+#endif
+			"smc	#0\n"
+			: "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3)
+			: "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4),
+			  "r" (r5)

And then add r6 here as an input

Review

Quoted 1 line
(quoted diff) +1 -0
+			: "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13",

And remove r6 from the clobber.

Quoted 5 lines
(quoted diff) +4 -0
+			"x14", "x15", "x16", "x17");
+
+	} while (r0 == QCOM_SCM_INTERRUPTED);
+

Review

Quoted 10 lines
(quoted diff) +10 -0
+	if (ret1)
+		*ret1 = r1;
+	if (ret2)
+		*ret2 = r2;
+	if (ret3)
+		*ret3 = r3;
+
+	return r0;
+}
+

Here's a totally untested patch for that.

----8<-----

drivers/firmware/qcom_scm-64.c +8 -4
index a95fd9b5d576..8f7e65ff524c 100644
@@ -114,6 +114,7 @@ int __qcom_scm_call_armv8_64(u64 x0, u64 x1, u64 x2, u64 x3, u64 x4, u64 x5,
  	register u64 r3 asm("r3") = x3;
  	register u64 r4 asm("r4") = x4;
  	register u64 r5 asm("r5") = x5;
+	register u64 r6 asm("r5") = 0;
  
  	do {
  		asm volatile(
@@ -127,14 +128,15 @@ int __qcom_scm_call_armv8_64(u64 x0, u64 x1, u64 x2, u64 x3, u64 x4, u64 x5,
  			__asmeq("%7", "x3")
  			__asmeq("%8", "x4")
  			__asmeq("%9", "x5")
+			__asmeq("%10", "x6")
  #ifdef REQUIRES_SEC
  			".arch_extension sec\n"
  #endif
  			"smc	#0\n"
  			: "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3)
  			: "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4),
-			  "r" (r5)
-			: "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13",
+			  "r" (r5), "r" (r6)
+			: "x7", "x8", "x9", "x10", "x11", "x12", "x13",
  			  "x14", "x15", "x16", "x17");
  	} while (r0 == QCOM_SCM_INTERRUPTED);
  
@@ -157,6 +159,7 @@ int __qcom_scm_call_armv8_32(u32 w0, u32 w1, u32 w2, u32 w3, u32 w4, u32 w5,
  	register u32 r3 asm("r3") = w3;
  	register u32 r4 asm("r4") = w4;
  	register u32 r5 asm("r5") = w5;
+	register u32 r6 asm("r6") = 0;
  
  	do {
  		asm volatile(
@@ -170,14 +173,15 @@ int __qcom_scm_call_armv8_32(u32 w0, u32 w1, u32 w2, u32 w3, u32 w4, u32 w5,
  			__asmeq("%7", "x3")
  			__asmeq("%8", "x4")
  			__asmeq("%9", "x5")
+			__asmeq("%10", "x6")
  #ifdef REQUIRES_SEC
  			".arch_extension sec\n"
  #endif
  			"smc	#0\n"
  			: "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3)
  			: "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4),
-			  "r" (r5)
-			: "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13",
+			  "r" (r5), "r" (r6)
+			: "x7", "x8", "x9", "x10", "x11", "x12", "x13",
  			"x14", "x15", "x16", "x17");
  
  	} while (r0 == QCOM_SCM_INTERRUPTED);
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
#7 lore raw

Re: [PATCH v5 2/2] firmware: qcom: scm: Add support for ARM64 SoCs

Quoted 172 lines · Stephen Boyd

Review

Quoted 10 lines · Kumar Gala
(quoted diff) +10 -0
+
+int __qcom_scm_call_armv8_64(u64 x0, u64 x1, u64 x2, u64 x3, u64 x4, u64 x5,
+				u64 *ret1, u64 *ret2, u64 *ret3)
+{
+	register u64 r0 asm("r0") = x0;
+	register u64 r1 asm("r1") = x1;
+	register u64 r2 asm("r2") = x2;
+	register u64 r3 asm("r3") = x3;
+	register u64 r4 asm("r4") = x4;
+	register u64 r5 asm("r5") = x5;

This should set x6 to 0.

    register u32 r6 asm("r6") = 0;

for example.

Review

Quoted 13 lines
(quoted diff) +13 -0
+
+	do {
+		asm volatile(
+			__asmeq("%0", "x0")
+			__asmeq("%1", "x1")
+			__asmeq("%2", "x2")
+			__asmeq("%3", "x3")
+			__asmeq("%4", "x0")
+			__asmeq("%5", "x1")
+			__asmeq("%6", "x2")
+			__asmeq("%7", "x3")
+			__asmeq("%8", "x4")
+			__asmeq("%9", "x5")

And then the asmeq thing here for x6.

Review

Quoted 7 lines
(quoted diff) +7 -0
+#ifdef REQUIRES_SEC
+			".arch_extension sec\n"
+#endif
+			"smc	#0\n"
+			: "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3)
+			: "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4),
+			  "r" (r5)

And add x6 as an input here.

Review

Quoted 1 line
(quoted diff) +1 -0
+			: "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13",

and remove x6 as a clobber.

Quoted 12 lines
(quoted diff) +12 -0
+			  "x14", "x15", "x16", "x17");
+	} while (r0 == QCOM_SCM_INTERRUPTED);
+
+	if (ret1)
+		*ret1 = r1;
+	if (ret2)
+		*ret2 = r2;
+	if (ret3)
+		*ret3 = r3;
+
+	return r0;
+}

Review

Quoted 10 lines
(quoted diff) +10 -0
+
+int __qcom_scm_call_armv8_32(u32 w0, u32 w1, u32 w2, u32 w3, u32 w4, u32 w5,
+				u64 *ret1, u64 *ret2, u64 *ret3)
+{
+	register u32 r0 asm("r0") = w0;
+	register u32 r1 asm("r1") = w1;
+	register u32 r2 asm("r2") = w2;
+	register u32 r3 asm("r3") = w3;
+	register u32 r4 asm("r4") = w4;
+	register u32 r5 asm("r5") = w5;

This needs to set r6 to 0 as well

    register u32 r6 asm("r6") = 0;

for example.

Review

Quoted 13 lines
(quoted diff) +13 -0
+
+	do {
+		asm volatile(
+			__asmeq("%0", "x0")
+			__asmeq("%1", "x1")
+			__asmeq("%2", "x2")
+			__asmeq("%3", "x3")
+			__asmeq("%4", "x0")
+			__asmeq("%5", "x1")
+			__asmeq("%6", "x2")
+			__asmeq("%7", "x3")
+			__asmeq("%8", "x4")
+			__asmeq("%9", "x5")

And then another asmeq thing here for x6.

Review

Quoted 7 lines
(quoted diff) +7 -0
+#ifdef REQUIRES_SEC
+			".arch_extension sec\n"
+#endif
+			"smc	#0\n"
+			: "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3)
+			: "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4),
+			  "r" (r5)

And then add r6 here as an input

Review

Quoted 1 line
(quoted diff) +1 -0
+			: "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13",

And remove r6 from the clobber.

Quoted 5 lines
(quoted diff) +4 -0
+			"x14", "x15", "x16", "x17");
+
+	} while (r0 == QCOM_SCM_INTERRUPTED);
+

Review

Quoted 10 lines
(quoted diff) +10 -0
+	if (ret1)
+		*ret1 = r1;
+	if (ret2)
+		*ret2 = r2;
+	if (ret3)
+		*ret3 = r3;
+
+	return r0;
+}
+

Here's a totally untested patch for that.

----8<-----

drivers/firmware/qcom_scm-64.c +6 -2
index a95fd9b5d576..8f7e65ff524c 100644
@@ -114,6 +114,7 @@ int __qcom_scm_call_armv8_64(u64 x0, u64 x1, u64 x2, u64 x3, u64 x4, u64 x5,
 	register u64 r3 asm("r3") = x3;
 	register u64 r4 asm("r4") = x4;
 	register u64 r5 asm("r5") = x5;
+	register u64 r6 asm("r5") = 0;
 	do {
 		asm volatile(
@@ -127,14 +128,15 @@ int __qcom_scm_call_armv8_64(u64 x0, u64 x1, u64 x2, u64 x3, u64 x4, u64 x5,
 			__asmeq("%7", "x3")
 			__asmeq("%8", "x4")
 			__asmeq("%9", "x5")
+			__asmeq("%10", "x6")
 #ifdef REQUIRES_SEC
 			".arch_extension sec\n"
 #endif
 			"smc	#0\n"
 			: "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3)
 			: "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4),
-			  "r" (r5)
-			: "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13",
+			  "r" (r5), "r" (r6)
+			: "x7", "x8", "x9", "x10", "x11", "x12", "x13",
 			  "x14", "x15", "x16", "x17");
 	} while (r0 == QCOM_SCM_INTERRUPTED);
@@ -157,6 +159,7 @@ int __qcom_scm_call_armv8_32(u32 w0, u32 w1, u32 w2, u32 w3, u32 w4, u32 w5,
 	register u32 r3 asm("r3") = w3;
 	register u32 r4 asm("r4") = w4;
 	register u32 r5 asm("r5") = w5;
+	register u32 r6 asm("r6") = 0;
 	do {
 		asm volatile(
@@ -170,14 +173,15 @@ int __qcom_scm_call_armv8_32(u32 w0, u32 w1, u32 w2, u32 w3, u32 w4, u32 w5,
 			__asmeq("%7", "x3")
 			__asmeq("%8", "x4")
 			__asmeq("%9", "x5")
+			__asmeq("%10", "x6")
 #ifdef REQUIRES_SEC
 			".arch_extension sec\n"
 #endif

drivers/firmware/qcom_scm-64.c int __qcom_scm_call_armv8_32(u32 w0, u32 w1, u32 w2, u32 w3, u32 w4, u32 w5, · line 187

Quoted 10 lines
drivers/firmware/qcom_scm-64.c +2 -2
 			"smc	#0\n"
 			: "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3)
 			: "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4),
-			  "r" (r5)
-			: "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13",
+			  "r" (r5), "r" (r6)
+			: "x7", "x8", "x9", "x10", "x11", "x12", "x13",
 			"x14", "x15", "x16", "x17");
 	} while (r0 == QCOM_SCM_INTERRUPTED);
 

Stephen, I'll incorporate this in the next version. Thanks!

Signature · 3 lines
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project