firmware: qcom: scm: Split out 32-bit specific SCM code
Subsystems (2)
PATCH v4 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.
---
drivers/firmware/Makefile | 3 +-
drivers/firmware/{qcom_scm.c => qcom_scm-32.c} | 15 +-
drivers/firmware/qcom_scm.c | 442 +------------------------
drivers/firmware/qcom_scm.h | 29 ++
4 files changed, 42 insertions(+), 447 deletions(-)
copy drivers/firmware/{qcom_scm.c => qcom_scm-32.c} (96%)
create mode 100644 drivers/firmware/qcom_scm.hdrivers/firmware/Makefile +2 -1
@@ -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 -11
@@ -27,6 +27,7 @@#include <asm/outercache.h> #include <asm/cacheflush.h> +#include "qcom_scm.h" #define QCOM_SCM_ENOMEM -5#define QCOM_SCM_EOPNOTSUPP -4
@@ -386,8 +387,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 +411,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 +434,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 +443,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 +471,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 +480,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 +29 -0
@@ -0,0 +1,29 @@ +/* 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); +#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
PATCH v4 2/2 firmware: qcom: scm: Add support for ARM64 SoCs
Add an implementation of the SCM interface that works on ARM64/64-bit SoCs
---
* 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 | 465 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 470 insertions(+) create mode 100644 drivers/firmware/qcom_scm-64.c
arch/arm64/Kconfig +1 -0
@@ -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
@@ -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 +465 -0
465 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
Re: [PATCH v4 2/2] firmware: qcom: scm: Add support for ARM64 SoCs
Hi Kumar,
Quoted 72 lines · Kumar Gala
drivers/firmware/qcom_scm-64.c new file +69
-0@@ -0,0 +1,465 @@ +/* Copyright (c) 2014-2015, 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. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +* 02110-1301, USA. +*/ + +#include <linux/cpumask.h> +#include <linux/delay.h> +#include <linux/mutex.h> +#include <linux/slab.h> +#include <linux/types.h> +#include <linux/qcom_scm.h> + +#include <asm/cacheflush.h> +#include <asm/compiler.h> +#include <asm/smp_plat.h> + +#include "qcom_scm.h" + +#define QCOM_SCM_SIP_FNID (s, c) (((((s) & 0xFF) << 8) | ((c) & 0xFF)) | 0x02000000) + +#define MAX_QCOM_SCM_ARGS 10 +#define MAX_QCOM_SCM_RETS 3 + +#define QCOM_SCM_ARGS_IMPL (num, a, b, c, d, e, f, g, h, i, j, ...) (\ + (((a) & 0xff) << 4) | \ + (((b) & 0xff) << 6) | \ + (((c) & 0xff) << 8) | \ + (((d) & 0xff) << 10) | \ + (((e) & 0xff) << 12) | \ + (((f) & 0xff) << 14) | \ + (((g) & 0xff) << 16) | \ + (((h) & 0xff) << 18) | \ + (((i) & 0xff) << 20) | \ + (((j) & 0xff) << 22) | \ + (num & 0xffff)) + +#define QCOM_SCM_ARGS (...) QCOM_SCM_ARGS_IMPL(__VA_ARGS__, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + +/** +* struct qcom_scm_desc +* @arginfo: Metadata describing the arguments in args[] +* @args: The array of arguments for the secure syscall +* @ret: The values returned by the secure syscall +* @extra_arg_buf: The buffer containing extra arguments +(that don't fit in available registers) +* @x5: The 4rd argument to the secure syscall or physical address of +extra_arg_buf +*/ +struct qcom_scm_desc { +u32 arginfo; +u64 args[MAX_QCOM_SCM_ARGS ]; +u64 ret[MAX_QCOM_SCM_RETS ]; + +/* private */ +void *extra_arg_buf; +u64 x5; +};
drivers/firmware/qcom_scm-64.c line 79
Quoted 10 lines
drivers/firmware/qcom_scm-64.c new file +10
-0+ + +#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 +#define QCOM_SCM_EBUSY -55 +#define QCOM_SCM_V2_EBUSY -12
Any reason to duplicate ENOMEM through INTERRUPTED rather than put them in the common header?
Quoted 9 lines
drivers/firmware/qcom_scm-64.c new file +9
-0+static DEFINE_MUTEX (qcom_scm_lock); + +#define QCOM_SCM_EBUSY_WAIT_MS 30 +#define QCOM_SCM_EBUSY_MAX_RETRY 20 + +#define N_EXT_QCOM_SCM_ARGS 7 +#define FIRST_EXT_ARG_IDX 3 +#define SMC_ATOMIC_SYSCALL 31 +#define N_REGISTER_ARGS (MAX_QCOM_SCM_ARGS - N_EXT_QCOM_SCM_ARGS + 1)
drivers/firmware/qcom_scm-64.c line 99
Quoted 10 lines
drivers/firmware/qcom_scm-64.c new file +10
-0+#define SMC64_MASK 0x40000000 +#define SMC_ATOMIC_MASK 0x80000000 +#define IS_CALL_AVAIL_CMD 1 + +#define R0_STR "x0" +#define R1_STR "x1" +#define R2_STR "x2" +#define R3_STR "x3" +#define R4_STR "x4" +#define R5_STR "x5"
What is the purpose of these macros?
Chris
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
Re: [PATCH v4 2/2] firmware: qcom: scm: Add support for ARM64 SoCs
Quoted 84 lines · Christopher Covington
Hi Kumar,
Quoted 77 lines · Kumar Gala
drivers/firmware/qcom_scm-64.c new file +74
-0@@ -0,0 +1,465 @@ +/* Copyright (c) 2014-2015, 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. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +* 02110-1301, USA. +*/ + +#include <linux/cpumask.h> +#include <linux/delay.h> +#include <linux/mutex.h> +#include <linux/slab.h> +#include <linux/types.h> +#include <linux/qcom_scm.h> + +#include <asm/cacheflush.h> +#include <asm/compiler.h> +#include <asm/smp_plat.h> + +#include "qcom_scm.h" + +#define QCOM_SCM_SIP_FNID (s, c) (((((s) & 0xFF) << 8) | ((c) & 0xFF)) | 0x02000000) + +#define MAX_QCOM_SCM_ARGS 10 +#define MAX_QCOM_SCM_RETS 3 + +#define QCOM_SCM_ARGS_IMPL (num, a, b, c, d, e, f, g, h, i, j, ...) (\ + (((a) & 0xff) << 4) | \ + (((b) & 0xff) << 6) | \ + (((c) & 0xff) << 8) | \ + (((d) & 0xff) << 10) | \ + (((e) & 0xff) << 12) | \ + (((f) & 0xff) << 14) | \ + (((g) & 0xff) << 16) | \ + (((h) & 0xff) << 18) | \ + (((i) & 0xff) << 20) | \ + (((j) & 0xff) << 22) | \ + (num & 0xffff)) + +#define QCOM_SCM_ARGS (...) QCOM_SCM_ARGS_IMPL(__VA_ARGS__, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + +/** +* struct qcom_scm_desc +* @arginfo: Metadata describing the arguments in args[] +* @args: The array of arguments for the secure syscall +* @ret: The values returned by the secure syscall +* @extra_arg_buf: The buffer containing extra arguments +(that don't fit in available registers) +* @x5: The 4rd argument to the secure syscall or physical address of +extra_arg_buf +*/ +struct qcom_scm_desc { +u32 arginfo; +u64 args[MAX_QCOM_SCM_ARGS ]; +u64 ret[MAX_QCOM_SCM_RETS ]; + +/* private */ +void *extra_arg_buf; +u64 x5; +}; + + +#define QCOM_SCM_ENOMEM -5 +#define QCOM_SCM_EOPNOTSUPP -4 +#define QCOM_SCM_EINVAL_ADDR -3
Quoted 8 lines
drivers/firmware/qcom_scm-64.c line 79
Quoted 5 lines
drivers/firmware/qcom_scm-64.c new file +5
-0+#define QCOM_SCM_EINVAL_ARG -2 +#define QCOM_SCM_ERROR -1 +#define QCOM_SCM_INTERRUPTED 1 +#define QCOM_SCM_EBUSY -55 +#define QCOM_SCM_V2_EBUSY -12Any reason to duplicate ENOMEM through INTERRUPTED rather than put them in the common header?
No reason to duplicate them, just hadn?t noticed.
Quoted 13 lines
Quoted 13 lines
drivers/firmware/qcom_scm-64.c new file +13
-0+static DEFINE_MUTEX (qcom_scm_lock); + +#define QCOM_SCM_EBUSY_WAIT_MS 30 +#define QCOM_SCM_EBUSY_MAX_RETRY 20 + +#define N_EXT_QCOM_SCM_ARGS 7 +#define FIRST_EXT_ARG_IDX 3 +#define SMC_ATOMIC_SYSCALL 31 +#define N_REGISTER_ARGS (MAX_QCOM_SCM_ARGS - N_EXT_QCOM_SCM_ARGS + 1) +#define SMC64_MASK 0x40000000 +#define SMC_ATOMIC_MASK 0x80000000 +#define IS_CALL_AVAIL_CMD 1 +
Quoted 8 lines
drivers/firmware/qcom_scm-64.c line 99
Quoted 6 lines
drivers/firmware/qcom_scm-64.c new file +6
-0+#define R0_STR "x0" +#define R1_STR "x1" +#define R2_STR "x2" +#define R3_STR "x3" +#define R4_STR "x4" +#define R5_STR "x5"What is the purpose of these macros?
Probably left over from when those code was merged between 32 and 64-bit, I?ll just inline them.
Thanks for the review.
- 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