linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/5] arm/arm64: smccc: Add ARCH_SOC_ID support
@ 2020-04-30 11:48 Sudeep Holla
  2020-04-30 11:48 ` [PATCH 1/5] arm/arm64: smccc: Update link to latest SMCCC specification Sudeep Holla
                   ` (4 more replies)
  0 siblings, 5 replies; 14+ messages in thread
From: Sudeep Holla @ 2020-04-30 11:48 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Mark Rutland, Lorenzo Pieralisi, Catalin Marinas, linux-kernel,
	Steven Price, harb, Sudeep Holla, Will Deacon

Hi,

This patch series adds support for SMCCCv1.2 ARCH_SOC_ID.
This doesn't add other changes added in SMCCC v1.2 yet. They will
follow these soon along with its first user SPCI/PSA-FF.

This is tested using upstream TF-A + the patch[1] fixing the original
implementation there.

Sudeep Holla (5):
  arm/arm64: smccc: Update link to latest SMCCC specification
  arm/arm64: smccc: Add the definition for SMCCCv1.2 version/error codes
  arm/arm64: smccc: Drop smccc_version enum and use ARM_SMCCC_VERSION_1_x instead
  firmware: psci: Add function to fetch SMCCC version
  arm/arm64: smccc: Add ARCH_SOC_ID support

--
Regards,
Sudeep

[1] https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/4001

 arch/arm64/kernel/paravirt.c   |   2 +-
 drivers/firmware/psci/Makefile |   2 +-
 drivers/firmware/psci/psci.c   |  13 ++-
 drivers/firmware/psci/soc_id.c | 148 +++++++++++++++++++++++++++++++++
 include/linux/arm-smccc.h      |  23 ++++-
 include/linux/psci.h           |   7 +-
 6 files changed, 181 insertions(+), 14 deletions(-)
 create mode 100644 drivers/firmware/psci/soc_id.c

--
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1/5] arm/arm64: smccc: Update link to latest SMCCC specification
  2020-04-30 11:48 [PATCH 0/5] arm/arm64: smccc: Add ARCH_SOC_ID support Sudeep Holla
@ 2020-04-30 11:48 ` Sudeep Holla
  2020-05-01 14:46   ` Steven Price
  2020-04-30 11:48 ` [PATCH 2/5] arm/arm64: smccc: Add the definition for SMCCCv1.2 version/error codes Sudeep Holla
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 14+ messages in thread
From: Sudeep Holla @ 2020-04-30 11:48 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Mark Rutland, Lorenzo Pieralisi, Catalin Marinas, linux-kernel,
	Steven Price, harb, Sudeep Holla, Will Deacon

The current link gets redirected to the revision B published in November
2016 though it actually points to the original revision A published in
June 2013.

Let us update the link to point to the latest version, so that it
doesn't get stal anytime soon. Currently it points to v1.2 published in
March 2020.

Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
 include/linux/arm-smccc.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
index 59494df0f55b..6c1d1eda3be4 100644
--- a/include/linux/arm-smccc.h
+++ b/include/linux/arm-smccc.h
@@ -10,7 +10,7 @@
 /*
  * This file provides common defines for ARM SMC Calling Convention as
  * specified in
- * http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
+ * https://developer.arm.com/docs/den0028/latest
  */
 
 #define ARM_SMCCC_STD_CALL	        _AC(0,U)
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 2/5] arm/arm64: smccc: Add the definition for SMCCCv1.2 version/error codes
  2020-04-30 11:48 [PATCH 0/5] arm/arm64: smccc: Add ARCH_SOC_ID support Sudeep Holla
  2020-04-30 11:48 ` [PATCH 1/5] arm/arm64: smccc: Update link to latest SMCCC specification Sudeep Holla
@ 2020-04-30 11:48 ` Sudeep Holla
  2020-05-01 14:46   ` Steven Price
  2020-04-30 11:48 ` [PATCH 3/5] arm/arm64: smccc: Drop smccc_version enum and use ARM_SMCCC_VERSION_1_x instead Sudeep Holla
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 14+ messages in thread
From: Sudeep Holla @ 2020-04-30 11:48 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Mark Rutland, Lorenzo Pieralisi, Catalin Marinas, linux-kernel,
	Steven Price, harb, Sudeep Holla, Will Deacon

Add the definition for SMCCC v1.2 version and new error code added.
While at it, also add a note that ARM DEN 0070A is deprecated and is
now merged into the main SMCCC specification(ARM DEN 0028C).

Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
 include/linux/arm-smccc.h | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
index 6c1d1eda3be4..9d9a2e42e919 100644
--- a/include/linux/arm-smccc.h
+++ b/include/linux/arm-smccc.h
@@ -56,6 +56,7 @@
 
 #define ARM_SMCCC_VERSION_1_0		0x10000
 #define ARM_SMCCC_VERSION_1_1		0x10001
+#define ARM_SMCCC_VERSION_1_2		0x10002
 
 #define ARM_SMCCC_VERSION_FUNC_ID					\
 	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
@@ -314,10 +315,14 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
  */
 #define arm_smccc_1_1_hvc(...)	__arm_smccc_1_1(SMCCC_HVC_INST, __VA_ARGS__)
 
-/* Return codes defined in ARM DEN 0070A */
+/*
+ * Return codes defined in ARM DEN 0070A
+ * ARM DEN 0070A is now merged/consolidated into ARM DEN 0028C
+ */
 #define SMCCC_RET_SUCCESS			0
 #define SMCCC_RET_NOT_SUPPORTED			-1
 #define SMCCC_RET_NOT_REQUIRED			-2
+#define SMCCC_RET_INVALID_PARAMETER		-3
 
 /*
  * Like arm_smccc_1_1* but always returns SMCCC_RET_NOT_SUPPORTED.
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 3/5] arm/arm64: smccc: Drop smccc_version enum and use ARM_SMCCC_VERSION_1_x instead
  2020-04-30 11:48 [PATCH 0/5] arm/arm64: smccc: Add ARCH_SOC_ID support Sudeep Holla
  2020-04-30 11:48 ` [PATCH 1/5] arm/arm64: smccc: Update link to latest SMCCC specification Sudeep Holla
  2020-04-30 11:48 ` [PATCH 2/5] arm/arm64: smccc: Add the definition for SMCCCv1.2 version/error codes Sudeep Holla
@ 2020-04-30 11:48 ` Sudeep Holla
  2020-05-01 14:48   ` Steven Price
  2020-04-30 11:48 ` [PATCH 4/5] firmware: psci: Add function to fetch SMCCC version Sudeep Holla
  2020-04-30 11:48 ` [PATCH 5/5] arm/arm64: smccc: Add ARCH_SOC_ID support Sudeep Holla
  4 siblings, 1 reply; 14+ messages in thread
From: Sudeep Holla @ 2020-04-30 11:48 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Mark Rutland, Lorenzo Pieralisi, Catalin Marinas, linux-kernel,
	Steven Price, harb, Sudeep Holla, Will Deacon

Instead of maintaining 2 sets of enums/macros for tracking SMCCC version,
let us drop smccc_version enum and use ARM_SMCCC_VERSION_1_x directly
instead.

Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
 arch/arm64/kernel/paravirt.c | 2 +-
 drivers/firmware/psci/psci.c | 8 ++++----
 include/linux/psci.h         | 7 +------
 3 files changed, 6 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/kernel/paravirt.c b/arch/arm64/kernel/paravirt.c
index 1ef702b0be2d..295d66490584 100644
--- a/arch/arm64/kernel/paravirt.c
+++ b/arch/arm64/kernel/paravirt.c
@@ -120,7 +120,7 @@ static bool has_pv_steal_clock(void)
 	struct arm_smccc_res res;
 
 	/* To detect the presence of PV time support we require SMCCC 1.1+ */
-	if (psci_ops.smccc_version < SMCCC_VERSION_1_1)
+	if (arm_smccc_1_1_get_conduit() == SMCCC_CONDUIT_NONE)
 		return false;
 
 	arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c
index 2937d44b5df4..6a56d7196697 100644
--- a/drivers/firmware/psci/psci.c
+++ b/drivers/firmware/psci/psci.c
@@ -54,12 +54,12 @@ bool psci_tos_resident_on(int cpu)
 
 struct psci_operations psci_ops = {
 	.conduit = SMCCC_CONDUIT_NONE,
-	.smccc_version = SMCCC_VERSION_1_0,
+	.smccc_version = ARM_SMCCC_VERSION_1_0,
 };
 
 enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void)
 {
-	if (psci_ops.smccc_version < SMCCC_VERSION_1_1)
+	if (psci_ops.smccc_version < ARM_SMCCC_VERSION_1_1)
 		return SMCCC_CONDUIT_NONE;
 
 	return psci_ops.conduit;
@@ -411,8 +411,8 @@ static void __init psci_init_smccc(void)
 	if (feature != PSCI_RET_NOT_SUPPORTED) {
 		u32 ret;
 		ret = invoke_psci_fn(ARM_SMCCC_VERSION_FUNC_ID, 0, 0, 0);
-		if (ret == ARM_SMCCC_VERSION_1_1) {
-			psci_ops.smccc_version = SMCCC_VERSION_1_1;
+		if (ret >= ARM_SMCCC_VERSION_1_1) {
+			psci_ops.smccc_version = ret;
 			ver = ret;
 		}
 	}
diff --git a/include/linux/psci.h b/include/linux/psci.h
index a67712b73b6c..29bd0671e5bb 100644
--- a/include/linux/psci.h
+++ b/include/linux/psci.h
@@ -21,11 +21,6 @@ bool psci_power_state_is_valid(u32 state);
 int psci_set_osi_mode(void);
 bool psci_has_osi_support(void);
 
-enum smccc_version {
-	SMCCC_VERSION_1_0,
-	SMCCC_VERSION_1_1,
-};
-
 struct psci_operations {
 	u32 (*get_version)(void);
 	int (*cpu_suspend)(u32 state, unsigned long entry_point);
@@ -36,7 +31,7 @@ struct psci_operations {
 			unsigned long lowest_affinity_level);
 	int (*migrate_info_type)(void);
 	enum arm_smccc_conduit conduit;
-	enum smccc_version smccc_version;
+	u32 smccc_version;
 };
 
 extern struct psci_operations psci_ops;
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 4/5] firmware: psci: Add function to fetch SMCCC version
  2020-04-30 11:48 [PATCH 0/5] arm/arm64: smccc: Add ARCH_SOC_ID support Sudeep Holla
                   ` (2 preceding siblings ...)
  2020-04-30 11:48 ` [PATCH 3/5] arm/arm64: smccc: Drop smccc_version enum and use ARM_SMCCC_VERSION_1_x instead Sudeep Holla
@ 2020-04-30 11:48 ` Sudeep Holla
  2020-04-30 11:48 ` [PATCH 5/5] arm/arm64: smccc: Add ARCH_SOC_ID support Sudeep Holla
  4 siblings, 0 replies; 14+ messages in thread
From: Sudeep Holla @ 2020-04-30 11:48 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Mark Rutland, Lorenzo Pieralisi, Catalin Marinas, linux-kernel,
	Steven Price, harb, Sudeep Holla, Will Deacon

For backward compatibility reasons, PSCI maintains SMCCC version as
SMCCC didn't provide ARM_SMCCC_VERSION_FUNC_ID until v1.1

Let us provide accessors to fetch the SMCCC version in PSCI so that
other SMCCC v1.1+ features can use it.

Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
 drivers/firmware/psci/psci.c | 5 +++++
 include/linux/arm-smccc.h    | 9 +++++++++
 2 files changed, 14 insertions(+)

diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c
index 6a56d7196697..04426e16fee6 100644
--- a/drivers/firmware/psci/psci.c
+++ b/drivers/firmware/psci/psci.c
@@ -65,6 +65,11 @@ enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void)
 	return psci_ops.conduit;
 }
 
+u32 arm_smccc_get_version(void)
+{
+	return psci_ops.smccc_version;
+}
+
 typedef unsigned long (psci_fn)(unsigned long, unsigned long,
 				unsigned long, unsigned long);
 static psci_fn *invoke_psci_fn;
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
index 9d9a2e42e919..d6b0f4acc707 100644
--- a/include/linux/arm-smccc.h
+++ b/include/linux/arm-smccc.h
@@ -98,6 +98,15 @@ enum arm_smccc_conduit {
  */
 enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void);
 
+/**
+ * arm_smccc_get_version()
+ *
+ * Returns the version to be used for SMCCCv1.1 or later.
+ *
+ * When SMCCCv1.1 or above is not present, assumes and returns SMCCCv1.0.
+ */
+u32 arm_smccc_get_version(void);
+
 /**
  * struct arm_smccc_res - Result from SMC/HVC call
  * @a0-a3 result values from registers 0 to 3
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 5/5] arm/arm64: smccc: Add ARCH_SOC_ID support
  2020-04-30 11:48 [PATCH 0/5] arm/arm64: smccc: Add ARCH_SOC_ID support Sudeep Holla
                   ` (3 preceding siblings ...)
  2020-04-30 11:48 ` [PATCH 4/5] firmware: psci: Add function to fetch SMCCC version Sudeep Holla
@ 2020-04-30 11:48 ` Sudeep Holla
  2020-05-01 15:07   ` Steven Price
  2020-05-01 15:25   ` John Garry
  4 siblings, 2 replies; 14+ messages in thread
From: Sudeep Holla @ 2020-04-30 11:48 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Mark Rutland, Lorenzo Pieralisi, Catalin Marinas, linux-kernel,
	Steven Price, harb, Sudeep Holla, Will Deacon

SMCCC v1.2 adds a new optional function SMCCC_ARCH_SOC_ID to obtain a
SiP defined SoC identification value. Add support for the same.

Also using the SoC bus infrastructure, let us expose the platform
specific SoC atrributes under sysfs. We also provide custom sysfs for
the vendor ID as JEP-106 bank and identification code.

Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
 drivers/firmware/psci/Makefile |   2 +-
 drivers/firmware/psci/soc_id.c | 148 +++++++++++++++++++++++++++++++++
 include/linux/arm-smccc.h      |   5 ++
 3 files changed, 154 insertions(+), 1 deletion(-)
 create mode 100644 drivers/firmware/psci/soc_id.c

diff --git a/drivers/firmware/psci/Makefile b/drivers/firmware/psci/Makefile
index 1956b882470f..c0b0c9ca57e4 100644
--- a/drivers/firmware/psci/Makefile
+++ b/drivers/firmware/psci/Makefile
@@ -1,4 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
 #
-obj-$(CONFIG_ARM_PSCI_FW)	+= psci.o
+obj-$(CONFIG_ARM_PSCI_FW)	+= psci.o soc_id.o
 obj-$(CONFIG_ARM_PSCI_CHECKER)	+= psci_checker.o
diff --git a/drivers/firmware/psci/soc_id.c b/drivers/firmware/psci/soc_id.c
new file mode 100644
index 000000000000..820f69dad7f5
--- /dev/null
+++ b/drivers/firmware/psci/soc_id.c
@@ -0,0 +1,148 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020 Arm Limited
+ */
+
+#include <linux/arm-smccc.h>
+#include <linux/bitfield.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/sys_soc.h>
+
+#define SOCID_JEP106_BANK_IDX_MASK	GENMASK(30, 24)
+#define SOCID_JEP106_ID_CODE_MASK	GENMASK(23, 16)
+#define SOCID_IMP_DEF_SOC_ID_MASK	GENMASK(15, 0)
+#define JEP106_BANK_IDX(x)	(u8)(FIELD_GET(SOCID_JEP106_BANK_IDX_MASK, (x)))
+#define JEP106_ID_CODE(x)	(u8)(FIELD_GET(SOCID_JEP106_ID_CODE_MASK, (x)))
+#define IMP_DEF_SOC_ID(x)	(u16)(FIELD_GET(SOCID_IMP_DEF_SOC_ID_MASK, (x)))
+
+static int soc_id_version;
+static struct soc_device *soc_dev;
+static struct soc_device_attribute *soc_dev_attr;
+
+static int smccc_map_error_codes(unsigned long a0)
+{
+	if (a0 == SMCCC_RET_INVALID_PARAMETER)
+		return -EINVAL;
+	if (a0 == SMCCC_RET_NOT_SUPPORTED)
+		return -EOPNOTSUPP;
+	return 0;
+}
+
+static int smccc_soc_id_support_check(void)
+{
+	struct arm_smccc_res res;
+
+	if (arm_smccc_1_1_get_conduit() == SMCCC_CONDUIT_NONE) {
+		pr_err("%s: invalid SMCCC conduit\n", __func__);
+		return -EOPNOTSUPP;
+	}
+
+	arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
+			     ARM_SMCCC_ARCH_SOC_ID, &res);
+
+	return smccc_map_error_codes(res.a0);
+}
+
+static ssize_t
+jep106_cont_bank_code_show(struct device *dev, struct device_attribute *attr,
+			   char *buf)
+{
+	return sprintf(buf, "%02x\n", JEP106_BANK_IDX(soc_id_version) + 1);
+}
+
+static DEVICE_ATTR_RO(jep106_cont_bank_code);
+
+static ssize_t
+jep106_identification_code_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%02x\n", JEP106_ID_CODE(soc_id_version) & 0x7F);
+}
+
+static DEVICE_ATTR_RO(jep106_identification_code);
+
+static struct attribute *jep106_id_attrs[] = {
+	&dev_attr_jep106_cont_bank_code.attr,
+	&dev_attr_jep106_identification_code.attr,
+	NULL
+};
+
+ATTRIBUTE_GROUPS(jep106_id);
+
+static int __init smccc_soc_init(void)
+{
+	struct device *dev;
+	int ret, soc_id_rev;
+	struct arm_smccc_res res;
+	static char soc_id_str[8], soc_id_rev_str[12];
+
+	if (arm_smccc_get_version() < ARM_SMCCC_VERSION_1_2)
+		return 0;
+
+	ret = smccc_soc_id_support_check();
+	if (ret)
+		return ret;
+
+	arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_SOC_ID, 0, &res);
+
+	ret = smccc_map_error_codes(res.a0);
+	if (ret)
+		return ret;
+
+	soc_id_version = res.a0;
+
+	arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_SOC_ID, 1, &res);
+
+	ret = smccc_map_error_codes(res.a0);
+	if (ret)
+		return ret;
+
+	soc_id_rev = res.a0;
+
+	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+	if (!soc_dev_attr)
+		return -ENOMEM;
+
+	sprintf(soc_id_str, "0x%04x", IMP_DEF_SOC_ID(soc_id_version));
+	sprintf(soc_id_rev_str, "0x%08x", soc_id_rev);
+
+	soc_dev_attr->soc_id = soc_id_str;
+	soc_dev_attr->revision = soc_id_rev_str;
+
+	soc_dev = soc_device_register(soc_dev_attr);
+	if (IS_ERR(soc_dev)) {
+		ret = PTR_ERR(soc_dev);
+		goto free_soc;
+	}
+
+	dev = soc_device_to_device(soc_dev);
+
+	ret = devm_device_add_groups(dev, jep106_id_groups);
+	if (ret) {
+		dev_err(dev, "sysfs create failed: %d\n", ret);
+		goto unregister_soc;
+	}
+
+	pr_info("SMCCC SoC ID: %s Revision %s\n", soc_dev_attr->soc_id,
+		soc_dev_attr->revision);
+
+	return 0;
+
+unregister_soc:
+	soc_device_unregister(soc_dev);
+free_soc:
+	kfree(soc_dev_attr);
+	return ret;
+}
+module_init(smccc_soc_init);
+
+static void __exit smccc_soc_exit(void)
+{
+	if (soc_dev)
+		soc_device_unregister(soc_dev);
+	kfree(soc_dev_attr);
+}
+module_exit(smccc_soc_exit);
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
index d6b0f4acc707..04414fc2000f 100644
--- a/include/linux/arm-smccc.h
+++ b/include/linux/arm-smccc.h
@@ -68,6 +68,11 @@
 			   ARM_SMCCC_SMC_32,				\
 			   0, 1)
 
+#define ARM_SMCCC_ARCH_SOC_ID						\
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
+			   ARM_SMCCC_SMC_32,				\
+			   0, 2)
+
 #define ARM_SMCCC_ARCH_WORKAROUND_1					\
 	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
 			   ARM_SMCCC_SMC_32,				\
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/5] arm/arm64: smccc: Update link to latest SMCCC specification
  2020-04-30 11:48 ` [PATCH 1/5] arm/arm64: smccc: Update link to latest SMCCC specification Sudeep Holla
@ 2020-05-01 14:46   ` Steven Price
  0 siblings, 0 replies; 14+ messages in thread
From: Steven Price @ 2020-05-01 14:46 UTC (permalink / raw)
  To: Sudeep Holla, linux-arm-kernel
  Cc: Mark Rutland, Lorenzo Pieralisi, Catalin Marinas, linux-kernel,
	harb, Will Deacon

On 30/04/2020 12:48, Sudeep Holla wrote:
> The current link gets redirected to the revision B published in November
> 2016 though it actually points to the original revision A published in
> June 2013.
> 
> Let us update the link to point to the latest version, so that it
> doesn't get stal anytime soon. Currently it points to v1.2 published in

s/stal/stale/

otherwise:

Reviewed-by: Steven Price <steven.price@arm.com>

> March 2020.
> 
> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
> ---
>   include/linux/arm-smccc.h | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
> index 59494df0f55b..6c1d1eda3be4 100644
> --- a/include/linux/arm-smccc.h
> +++ b/include/linux/arm-smccc.h
> @@ -10,7 +10,7 @@
>   /*
>    * This file provides common defines for ARM SMC Calling Convention as
>    * specified in
> - * http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
> + * https://developer.arm.com/docs/den0028/latest
>    */
>   
>   #define ARM_SMCCC_STD_CALL	        _AC(0,U)
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/5] arm/arm64: smccc: Add the definition for SMCCCv1.2 version/error codes
  2020-04-30 11:48 ` [PATCH 2/5] arm/arm64: smccc: Add the definition for SMCCCv1.2 version/error codes Sudeep Holla
@ 2020-05-01 14:46   ` Steven Price
  0 siblings, 0 replies; 14+ messages in thread
From: Steven Price @ 2020-05-01 14:46 UTC (permalink / raw)
  To: Sudeep Holla, linux-arm-kernel
  Cc: Mark Rutland, Lorenzo Pieralisi, Catalin Marinas, linux-kernel,
	harb, Will Deacon

On 30/04/2020 12:48, Sudeep Holla wrote:
> Add the definition for SMCCC v1.2 version and new error code added.
> While at it, also add a note that ARM DEN 0070A is deprecated and is
> now merged into the main SMCCC specification(ARM DEN 0028C).
> 
> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>

Reviewed-by: Steven Price <steven.price@arm.com>

> ---
>   include/linux/arm-smccc.h | 7 ++++++-
>   1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
> index 6c1d1eda3be4..9d9a2e42e919 100644
> --- a/include/linux/arm-smccc.h
> +++ b/include/linux/arm-smccc.h
> @@ -56,6 +56,7 @@
>   
>   #define ARM_SMCCC_VERSION_1_0		0x10000
>   #define ARM_SMCCC_VERSION_1_1		0x10001
> +#define ARM_SMCCC_VERSION_1_2		0x10002
>   
>   #define ARM_SMCCC_VERSION_FUNC_ID					\
>   	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
> @@ -314,10 +315,14 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
>    */
>   #define arm_smccc_1_1_hvc(...)	__arm_smccc_1_1(SMCCC_HVC_INST, __VA_ARGS__)
>   
> -/* Return codes defined in ARM DEN 0070A */
> +/*
> + * Return codes defined in ARM DEN 0070A
> + * ARM DEN 0070A is now merged/consolidated into ARM DEN 0028C
> + */
>   #define SMCCC_RET_SUCCESS			0
>   #define SMCCC_RET_NOT_SUPPORTED			-1
>   #define SMCCC_RET_NOT_REQUIRED			-2
> +#define SMCCC_RET_INVALID_PARAMETER		-3
>   
>   /*
>    * Like arm_smccc_1_1* but always returns SMCCC_RET_NOT_SUPPORTED.
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 3/5] arm/arm64: smccc: Drop smccc_version enum and use ARM_SMCCC_VERSION_1_x instead
  2020-04-30 11:48 ` [PATCH 3/5] arm/arm64: smccc: Drop smccc_version enum and use ARM_SMCCC_VERSION_1_x instead Sudeep Holla
@ 2020-05-01 14:48   ` Steven Price
  0 siblings, 0 replies; 14+ messages in thread
From: Steven Price @ 2020-05-01 14:48 UTC (permalink / raw)
  To: Sudeep Holla, linux-arm-kernel
  Cc: Mark Rutland, Lorenzo Pieralisi, Catalin Marinas, linux-kernel,
	harb, Will Deacon

On 30/04/2020 12:48, Sudeep Holla wrote:
> Instead of maintaining 2 sets of enums/macros for tracking SMCCC version,
> let us drop smccc_version enum and use ARM_SMCCC_VERSION_1_x directly
> instead.
> 
> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>

Reviewed-by: Steven Price <steven.price@arm.com>

> ---
>   arch/arm64/kernel/paravirt.c | 2 +-
>   drivers/firmware/psci/psci.c | 8 ++++----
>   include/linux/psci.h         | 7 +------
>   3 files changed, 6 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/arm64/kernel/paravirt.c b/arch/arm64/kernel/paravirt.c
> index 1ef702b0be2d..295d66490584 100644
> --- a/arch/arm64/kernel/paravirt.c
> +++ b/arch/arm64/kernel/paravirt.c
> @@ -120,7 +120,7 @@ static bool has_pv_steal_clock(void)
>   	struct arm_smccc_res res;
>   
>   	/* To detect the presence of PV time support we require SMCCC 1.1+ */
> -	if (psci_ops.smccc_version < SMCCC_VERSION_1_1)
> +	if (arm_smccc_1_1_get_conduit() == SMCCC_CONDUIT_NONE)
>   		return false;
>   
>   	arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
> diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c
> index 2937d44b5df4..6a56d7196697 100644
> --- a/drivers/firmware/psci/psci.c
> +++ b/drivers/firmware/psci/psci.c
> @@ -54,12 +54,12 @@ bool psci_tos_resident_on(int cpu)
>   
>   struct psci_operations psci_ops = {
>   	.conduit = SMCCC_CONDUIT_NONE,
> -	.smccc_version = SMCCC_VERSION_1_0,
> +	.smccc_version = ARM_SMCCC_VERSION_1_0,
>   };
>   
>   enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void)
>   {
> -	if (psci_ops.smccc_version < SMCCC_VERSION_1_1)
> +	if (psci_ops.smccc_version < ARM_SMCCC_VERSION_1_1)
>   		return SMCCC_CONDUIT_NONE;
>   
>   	return psci_ops.conduit;
> @@ -411,8 +411,8 @@ static void __init psci_init_smccc(void)
>   	if (feature != PSCI_RET_NOT_SUPPORTED) {
>   		u32 ret;
>   		ret = invoke_psci_fn(ARM_SMCCC_VERSION_FUNC_ID, 0, 0, 0);
> -		if (ret == ARM_SMCCC_VERSION_1_1) {
> -			psci_ops.smccc_version = SMCCC_VERSION_1_1;
> +		if (ret >= ARM_SMCCC_VERSION_1_1) {
> +			psci_ops.smccc_version = ret;
>   			ver = ret;
>   		}
>   	}
> diff --git a/include/linux/psci.h b/include/linux/psci.h
> index a67712b73b6c..29bd0671e5bb 100644
> --- a/include/linux/psci.h
> +++ b/include/linux/psci.h
> @@ -21,11 +21,6 @@ bool psci_power_state_is_valid(u32 state);
>   int psci_set_osi_mode(void);
>   bool psci_has_osi_support(void);
>   
> -enum smccc_version {
> -	SMCCC_VERSION_1_0,
> -	SMCCC_VERSION_1_1,
> -};
> -
>   struct psci_operations {
>   	u32 (*get_version)(void);
>   	int (*cpu_suspend)(u32 state, unsigned long entry_point);
> @@ -36,7 +31,7 @@ struct psci_operations {
>   			unsigned long lowest_affinity_level);
>   	int (*migrate_info_type)(void);
>   	enum arm_smccc_conduit conduit;
> -	enum smccc_version smccc_version;
> +	u32 smccc_version;
>   };
>   
>   extern struct psci_operations psci_ops;
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 5/5] arm/arm64: smccc: Add ARCH_SOC_ID support
  2020-04-30 11:48 ` [PATCH 5/5] arm/arm64: smccc: Add ARCH_SOC_ID support Sudeep Holla
@ 2020-05-01 15:07   ` Steven Price
  2020-05-01 15:57     ` Sudeep Holla
  2020-05-01 15:25   ` John Garry
  1 sibling, 1 reply; 14+ messages in thread
From: Steven Price @ 2020-05-01 15:07 UTC (permalink / raw)
  To: Sudeep Holla, linux-arm-kernel
  Cc: Mark Rutland, Lorenzo Pieralisi, Catalin Marinas, linux-kernel,
	Harb Abdulhamid (harb@amperecomputing.com),
	Will Deacon

On 30/04/2020 12:48, Sudeep Holla wrote:
> SMCCC v1.2 adds a new optional function SMCCC_ARCH_SOC_ID to obtain a
> SiP defined SoC identification value. Add support for the same.
> 
> Also using the SoC bus infrastructure, let us expose the platform
> specific SoC atrributes under sysfs. We also provide custom sysfs for
> the vendor ID as JEP-106 bank and identification code.
> 
> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
> ---
>   drivers/firmware/psci/Makefile |   2 +-
>   drivers/firmware/psci/soc_id.c | 148 +++++++++++++++++++++++++++++++++
>   include/linux/arm-smccc.h      |   5 ++
>   3 files changed, 154 insertions(+), 1 deletion(-)
>   create mode 100644 drivers/firmware/psci/soc_id.c
> 
> diff --git a/drivers/firmware/psci/Makefile b/drivers/firmware/psci/Makefile
> index 1956b882470f..c0b0c9ca57e4 100644
> --- a/drivers/firmware/psci/Makefile
> +++ b/drivers/firmware/psci/Makefile
> @@ -1,4 +1,4 @@
>   # SPDX-License-Identifier: GPL-2.0
>   #
> -obj-$(CONFIG_ARM_PSCI_FW)	+= psci.o
> +obj-$(CONFIG_ARM_PSCI_FW)	+= psci.o soc_id.o
>   obj-$(CONFIG_ARM_PSCI_CHECKER)	+= psci_checker.o
> diff --git a/drivers/firmware/psci/soc_id.c b/drivers/firmware/psci/soc_id.c
> new file mode 100644
> index 000000000000..820f69dad7f5
> --- /dev/null
> +++ b/drivers/firmware/psci/soc_id.c
> @@ -0,0 +1,148 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright 2020 Arm Limited
> + */
> +
> +#include <linux/arm-smccc.h>
> +#include <linux/bitfield.h>
> +#include <linux/device.h>
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/slab.h>
> +#include <linux/sys_soc.h>
> +
> +#define SOCID_JEP106_BANK_IDX_MASK	GENMASK(30, 24)
> +#define SOCID_JEP106_ID_CODE_MASK	GENMASK(23, 16)
> +#define SOCID_IMP_DEF_SOC_ID_MASK	GENMASK(15, 0)
> +#define JEP106_BANK_IDX(x)	(u8)(FIELD_GET(SOCID_JEP106_BANK_IDX_MASK, (x)))
> +#define JEP106_ID_CODE(x)	(u8)(FIELD_GET(SOCID_JEP106_ID_CODE_MASK, (x)))
> +#define IMP_DEF_SOC_ID(x)	(u16)(FIELD_GET(SOCID_IMP_DEF_SOC_ID_MASK, (x)))
> +
> +static int soc_id_version;
> +static struct soc_device *soc_dev;
> +static struct soc_device_attribute *soc_dev_attr;
> +
> +static int smccc_map_error_codes(unsigned long a0)
> +{
> +	if (a0 == SMCCC_RET_INVALID_PARAMETER)
> +		return -EINVAL;
> +	if (a0 == SMCCC_RET_NOT_SUPPORTED)
> +		return -EOPNOTSUPP;
> +	return 0;

It seems odd to special case just those errors. While they are the only 
errors we expect, any result with the high bit set is an error (arguably 
a bug in the firmware) so should really cause an error return.

> +}
> +
> +static int smccc_soc_id_support_check(void)
> +{
> +	struct arm_smccc_res res;
> +
> +	if (arm_smccc_1_1_get_conduit() == SMCCC_CONDUIT_NONE) {
> +		pr_err("%s: invalid SMCCC conduit\n", __func__);
> +		return -EOPNOTSUPP;
> +	}
> +
> +	arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
> +			     ARM_SMCCC_ARCH_SOC_ID, &res);
> +
> +	return smccc_map_error_codes(res.a0);
> +}
> +
> +static ssize_t
> +jep106_cont_bank_code_show(struct device *dev, struct device_attribute *attr,
> +			   char *buf)
> +{
> +	return sprintf(buf, "%02x\n", JEP106_BANK_IDX(soc_id_version) + 1);
> +}
> +
> +static DEVICE_ATTR_RO(jep106_cont_bank_code);
> +
> +static ssize_t
> +jep106_identification_code_show(struct device *dev,
> +				struct device_attribute *attr, char *buf)
> +{
> +	return sprintf(buf, "%02x\n", JEP106_ID_CODE(soc_id_version) & 0x7F);

It seems odd to have the mask defined to include a bit that is then 
always masked off. From the spec I presume this is a parity bit, but it 
would be good to have a comment explaining this.

> +}
> +
> +static DEVICE_ATTR_RO(jep106_identification_code);
> +
> +static struct attribute *jep106_id_attrs[] = {
> +	&dev_attr_jep106_cont_bank_code.attr,
> +	&dev_attr_jep106_identification_code.attr,
> +	NULL
> +};
> +
> +ATTRIBUTE_GROUPS(jep106_id);
> +
> +static int __init smccc_soc_init(void)
> +{
> +	struct device *dev;
> +	int ret, soc_id_rev;
> +	struct arm_smccc_res res;
> +	static char soc_id_str[8], soc_id_rev_str[12];
> +
> +	if (arm_smccc_get_version() < ARM_SMCCC_VERSION_1_2)
> +		return 0;

NIT: Do we actually need to check the version here - or would probing 
ARM_SMCCC_ARCH_FEATURES_FUNC_ID as is done below sufficient? I'm not 
aware of this relying on any new semantics that v1.2 added.

> +
> +	ret = smccc_soc_id_support_check();
> +	if (ret)
> +		return ret;

This seems odd - if the version is <v1.2 then we return 0. But if it's 
 >=1.2 but doesn't support SOC_ID then it's an error return?

> +
> +	arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_SOC_ID, 0, &res);
> +
> +	ret = smccc_map_error_codes(res.a0);
> +	if (ret)
> +		return ret;
> +
> +	soc_id_version = res.a0;
> +
> +	arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_SOC_ID, 1, &res);
> +
> +	ret = smccc_map_error_codes(res.a0);
> +	if (ret)
> +		return ret;
> +
> +	soc_id_rev = res.a0;
> +
> +	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
> +	if (!soc_dev_attr)
> +		return -ENOMEM;
> +
> +	sprintf(soc_id_str, "0x%04x", IMP_DEF_SOC_ID(soc_id_version));
> +	sprintf(soc_id_rev_str, "0x%08x", soc_id_rev);
> +
> +	soc_dev_attr->soc_id = soc_id_str;
> +	soc_dev_attr->revision = soc_id_rev_str;
> +
> +	soc_dev = soc_device_register(soc_dev_attr);
> +	if (IS_ERR(soc_dev)) {
> +		ret = PTR_ERR(soc_dev);
> +		goto free_soc;
> +	}
> +
> +	dev = soc_device_to_device(soc_dev);
> +
> +	ret = devm_device_add_groups(dev, jep106_id_groups);
> +	if (ret) {
> +		dev_err(dev, "sysfs create failed: %d\n", ret);
> +		goto unregister_soc;
> +	}
> +
> +	pr_info("SMCCC SoC ID: %s Revision %s\n", soc_dev_attr->soc_id,
> +		soc_dev_attr->revision);
> +
> +	return 0;
> +
> +unregister_soc:
> +	soc_device_unregister(soc_dev);
> +free_soc:
> +	kfree(soc_dev_attr);
> +	return ret;
> +}
> +module_init(smccc_soc_init);
> +
> +static void __exit smccc_soc_exit(void)
> +{
> +	if (soc_dev)
> +		soc_device_unregister(soc_dev);
> +	kfree(soc_dev_attr);
> +}
> +module_exit(smccc_soc_exit);
> diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
> index d6b0f4acc707..04414fc2000f 100644
> --- a/include/linux/arm-smccc.h
> +++ b/include/linux/arm-smccc.h
> @@ -68,6 +68,11 @@
>   			   ARM_SMCCC_SMC_32,				\
>   			   0, 1)
>   
> +#define ARM_SMCCC_ARCH_SOC_ID						\
> +	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
> +			   ARM_SMCCC_SMC_32,				\
> +			   0, 2)
> +
>   #define ARM_SMCCC_ARCH_WORKAROUND_1					\
>   	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
>   			   ARM_SMCCC_SMC_32,				\
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 5/5] arm/arm64: smccc: Add ARCH_SOC_ID support
  2020-04-30 11:48 ` [PATCH 5/5] arm/arm64: smccc: Add ARCH_SOC_ID support Sudeep Holla
  2020-05-01 15:07   ` Steven Price
@ 2020-05-01 15:25   ` John Garry
  2020-05-01 16:05     ` Sudeep Holla
  1 sibling, 1 reply; 14+ messages in thread
From: John Garry @ 2020-05-01 15:25 UTC (permalink / raw)
  To: Sudeep Holla, linux-arm-kernel
  Cc: Mark Rutland, Lorenzo Pieralisi, Catalin Marinas, linux-kernel,
	Steven Price, harb, Will Deacon

On 30/04/2020 12:48, Sudeep Holla wrote:
> +static int __init smccc_soc_init(void)
> +{
> +	struct device *dev;
> +	int ret, soc_id_rev;
> +	struct arm_smccc_res res;
> +	static char soc_id_str[8], soc_id_rev_str[12];
> +
> +	if (arm_smccc_get_version() < ARM_SMCCC_VERSION_1_2)
> +		return 0;
> +
> +	ret = smccc_soc_id_support_check();
> +	if (ret)
> +		return ret;
> +
> +	arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_SOC_ID, 0, &res);
> +
> +	ret = smccc_map_error_codes(res.a0);
> +	if (ret)
> +		return ret;
> +
> +	soc_id_version = res.a0;
> +
> +	arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_SOC_ID, 1, &res);
> +
> +	ret = smccc_map_error_codes(res.a0);
> +	if (ret)
> +		return ret;
> +
> +	soc_id_rev = res.a0;
> +
> +	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
> +	if (!soc_dev_attr)
> +		return -ENOMEM;
> +
> +	sprintf(soc_id_str, "0x%04x", IMP_DEF_SOC_ID(soc_id_version));
> +	sprintf(soc_id_rev_str, "0x%08x", soc_id_rev);
> +
> +	soc_dev_attr->soc_id = soc_id_str;
> +	soc_dev_attr->revision = soc_id_rev_str;
> +
> +	soc_dev = soc_device_register(soc_dev_attr);
> +	if (IS_ERR(soc_dev)) {
> +		ret = PTR_ERR(soc_dev);
> +		goto free_soc;
> +	}
> +
> +	dev = soc_device_to_device(soc_dev);
> +

Just wondering, what about if the platform already had a SoC driver - 
now it could have another one, such that we may have multiple sysfs soc 
devices, right?

Thanks,
John

> +	ret = devm_device_add_groups(dev, jep106_id_groups);
> +	if (ret) {
> +		dev_err(dev, "sysfs create failed: %d\n", ret);
> +		goto unregister_soc;
> +	}
> +
> +	pr_info("SMCCC SoC ID: %s Revision %s\n", soc_dev_attr->soc_id,
> +		soc_dev_attr->revision);
> +
> +	return 0;


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 5/5] arm/arm64: smccc: Add ARCH_SOC_ID support
  2020-05-01 15:07   ` Steven Price
@ 2020-05-01 15:57     ` Sudeep Holla
  0 siblings, 0 replies; 14+ messages in thread
From: Sudeep Holla @ 2020-05-01 15:57 UTC (permalink / raw)
  To: Steven Price
  Cc: Mark Rutland, Lorenzo Pieralisi, Catalin Marinas, linux-kernel,
	Harb Abdulhamid (harb@amperecomputing.com),
	Sudeep Holla, Will Deacon, linux-arm-kernel

Hi Steve,

Thanks for taking a reviewing these patches.

On Fri, May 01, 2020 at 04:07:39PM +0100, Steven Price wrote:
> On 30/04/2020 12:48, Sudeep Holla wrote:
> > SMCCC v1.2 adds a new optional function SMCCC_ARCH_SOC_ID to obtain a
> > SiP defined SoC identification value. Add support for the same.
> >
> > Also using the SoC bus infrastructure, let us expose the platform
> > specific SoC atrributes under sysfs. We also provide custom sysfs for
> > the vendor ID as JEP-106 bank and identification code.
> >
> > Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
> > ---
> >   drivers/firmware/psci/Makefile |   2 +-
> >   drivers/firmware/psci/soc_id.c | 148 +++++++++++++++++++++++++++++++++
> >   include/linux/arm-smccc.h      |   5 ++
> >   3 files changed, 154 insertions(+), 1 deletion(-)
> >   create mode 100644 drivers/firmware/psci/soc_id.c
> >
> > diff --git a/drivers/firmware/psci/Makefile b/drivers/firmware/psci/Makefile
> > index 1956b882470f..c0b0c9ca57e4 100644
> > --- a/drivers/firmware/psci/Makefile
> > +++ b/drivers/firmware/psci/Makefile
> > @@ -1,4 +1,4 @@
> >   # SPDX-License-Identifier: GPL-2.0
> >   #
> > -obj-$(CONFIG_ARM_PSCI_FW)	+= psci.o
> > +obj-$(CONFIG_ARM_PSCI_FW)	+= psci.o soc_id.o
> >   obj-$(CONFIG_ARM_PSCI_CHECKER)	+= psci_checker.o
> > diff --git a/drivers/firmware/psci/soc_id.c b/drivers/firmware/psci/soc_id.c
> > new file mode 100644
> > index 000000000000..820f69dad7f5
> > --- /dev/null
> > +++ b/drivers/firmware/psci/soc_id.c
> > @@ -0,0 +1,148 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright 2020 Arm Limited
> > + */
> > +
> > +#include <linux/arm-smccc.h>
> > +#include <linux/bitfield.h>
> > +#include <linux/device.h>
> > +#include <linux/module.h>
> > +#include <linux/kernel.h>
> > +#include <linux/slab.h>
> > +#include <linux/sys_soc.h>
> > +
> > +#define SOCID_JEP106_BANK_IDX_MASK	GENMASK(30, 24)
> > +#define SOCID_JEP106_ID_CODE_MASK	GENMASK(23, 16)
> > +#define SOCID_IMP_DEF_SOC_ID_MASK	GENMASK(15, 0)
> > +#define JEP106_BANK_IDX(x)	(u8)(FIELD_GET(SOCID_JEP106_BANK_IDX_MASK, (x)))
> > +#define JEP106_ID_CODE(x)	(u8)(FIELD_GET(SOCID_JEP106_ID_CODE_MASK, (x)))
> > +#define IMP_DEF_SOC_ID(x)	(u16)(FIELD_GET(SOCID_IMP_DEF_SOC_ID_MASK, (x)))
> > +
> > +static int soc_id_version;
> > +static struct soc_device *soc_dev;
> > +static struct soc_device_attribute *soc_dev_attr;
> > +
> > +static int smccc_map_error_codes(unsigned long a0)
> > +{
> > +	if (a0 == SMCCC_RET_INVALID_PARAMETER)
> > +		return -EINVAL;
> > +	if (a0 == SMCCC_RET_NOT_SUPPORTED)
> > +		return -EOPNOTSUPP;
> > +	return 0;
>
> It seems odd to special case just those errors. While they are the only
> errors we expect, any result with the high bit set is an error (arguably a
> bug in the firmware) so should really cause an error return.
>

I agree and happy to change it. I too thought about the same for a while and
they left it for review time to finalise 😄 

> > +}
> > +
> > +static int smccc_soc_id_support_check(void)
> > +{
> > +	struct arm_smccc_res res;
> > +
> > +	if (arm_smccc_1_1_get_conduit() == SMCCC_CONDUIT_NONE) {
> > +		pr_err("%s: invalid SMCCC conduit\n", __func__);
> > +		return -EOPNOTSUPP;
> > +	}
> > +
> > +	arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
> > +			     ARM_SMCCC_ARCH_SOC_ID, &res);
> > +
> > +	return smccc_map_error_codes(res.a0);
> > +}
> > +
> > +static ssize_t
> > +jep106_cont_bank_code_show(struct device *dev, struct device_attribute *attr,
> > +			   char *buf)
> > +{
> > +	return sprintf(buf, "%02x\n", JEP106_BANK_IDX(soc_id_version) + 1);
> > +}
> > +
> > +static DEVICE_ATTR_RO(jep106_cont_bank_code);
> > +
> > +static ssize_t
> > +jep106_identification_code_show(struct device *dev,
> > +				struct device_attribute *attr, char *buf)
> > +{
> > +	return sprintf(buf, "%02x\n", JEP106_ID_CODE(soc_id_version) & 0x7F);
>
> It seems odd to have the mask defined to include a bit that is then always
> masked off. From the spec I presume this is a parity bit, but it would be
> good to have a comment explaining this.
>

Sure, actually I can to make it part of the macro itself and add a note
there.

> > +}
> > +
> > +static DEVICE_ATTR_RO(jep106_identification_code);
> > +
> > +static struct attribute *jep106_id_attrs[] = {
> > +	&dev_attr_jep106_cont_bank_code.attr,
> > +	&dev_attr_jep106_identification_code.attr,
> > +	NULL
> > +};
> > +
> > +ATTRIBUTE_GROUPS(jep106_id);
> > +
> > +static int __init smccc_soc_init(void)
> > +{
> > +	struct device *dev;
> > +	int ret, soc_id_rev;
> > +	struct arm_smccc_res res;
> > +	static char soc_id_str[8], soc_id_rev_str[12];
> > +
> > +	if (arm_smccc_get_version() < ARM_SMCCC_VERSION_1_2)
> > +		return 0;
>
> NIT: Do we actually need to check the version here - or would probing
> ARM_SMCCC_ARCH_FEATURES_FUNC_ID as is done below sufficient? I'm not aware
> of this relying on any new semantics that v1.2 added.
>

It should be sufficient, but I am trying to avoid raising error if it is
not SMCCC v1.2+, hence the return 0.

> > +
> > +	ret = smccc_soc_id_support_check();
> > +	if (ret)
> > +		return ret;
>
> This seems odd - if the version is <v1.2 then we return 0. But if it's >=1.2
> but doesn't support SOC_ID then it's an error return?
>

You are right, I see that now. I can flag a note/info and return 0.

--
Regards,
Sudeep

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 5/5] arm/arm64: smccc: Add ARCH_SOC_ID support
  2020-05-01 15:25   ` John Garry
@ 2020-05-01 16:05     ` Sudeep Holla
  2020-05-01 16:40       ` John Garry
  0 siblings, 1 reply; 14+ messages in thread
From: Sudeep Holla @ 2020-05-01 16:05 UTC (permalink / raw)
  To: John Garry
  Cc: Mark Rutland, Lorenzo Pieralisi, Catalin Marinas, linux-kernel,
	Steven Price, harb, Sudeep Holla, Will Deacon, linux-arm-kernel

On Fri, May 01, 2020 at 04:25:27PM +0100, John Garry wrote:
> On 30/04/2020 12:48, Sudeep Holla wrote:
> > +static int __init smccc_soc_init(void)
> > +{
> > +	struct device *dev;
> > +	int ret, soc_id_rev;
> > +	struct arm_smccc_res res;
> > +	static char soc_id_str[8], soc_id_rev_str[12];
> > +
> > +	if (arm_smccc_get_version() < ARM_SMCCC_VERSION_1_2)
> > +		return 0;
> > +
> > +	ret = smccc_soc_id_support_check();
> > +	if (ret)
> > +		return ret;
> > +
> > +	arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_SOC_ID, 0, &res);
> > +
> > +	ret = smccc_map_error_codes(res.a0);
> > +	if (ret)
> > +		return ret;
> > +
> > +	soc_id_version = res.a0;
> > +
> > +	arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_SOC_ID, 1, &res);
> > +
> > +	ret = smccc_map_error_codes(res.a0);
> > +	if (ret)
> > +		return ret;
> > +
> > +	soc_id_rev = res.a0;
> > +
> > +	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
> > +	if (!soc_dev_attr)
> > +		return -ENOMEM;
> > +
> > +	sprintf(soc_id_str, "0x%04x", IMP_DEF_SOC_ID(soc_id_version));
> > +	sprintf(soc_id_rev_str, "0x%08x", soc_id_rev);
> > +
> > +	soc_dev_attr->soc_id = soc_id_str;
> > +	soc_dev_attr->revision = soc_id_rev_str;
> > +
> > +	soc_dev = soc_device_register(soc_dev_attr);
> > +	if (IS_ERR(soc_dev)) {
> > +		ret = PTR_ERR(soc_dev);
> > +		goto free_soc;
> > +	}
> > +
> > +	dev = soc_device_to_device(soc_dev);
> > +
>
> Just wondering, what about if the platform already had a SoC driver - now it
> could have another one, such that we may have multiple sysfs soc devices,
> right?
>

Yes I had a quick look at that.

1. Such platform has option not to implement this SOC_ID if it doesn't
   really require it.

2. If the firmware starts implementing it on some variants, then we can
   distinguish them with compatibles and blacklist them from the other
   SoC driver if having both is an issue

3. SoC bus layer supports adding multiple SoC ID driver and it may show
   up as /sys/devices/soc<n> which may or may not be fine. But this
   happens only if neither [1] nor [2] is done. I am happy to see if there's
   any solution for this. Any suggestions ?

--
Regards,
Sudeep

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 5/5] arm/arm64: smccc: Add ARCH_SOC_ID support
  2020-05-01 16:05     ` Sudeep Holla
@ 2020-05-01 16:40       ` John Garry
  0 siblings, 0 replies; 14+ messages in thread
From: John Garry @ 2020-05-01 16:40 UTC (permalink / raw)
  To: Sudeep Holla
  Cc: Mark Rutland, Lorenzo Pieralisi, Catalin Marinas, linux-kernel,
	Steven Price, harb, Will Deacon, linux-arm-kernel

On 01/05/2020 17:05, Sudeep Holla wrote:
> On Fri, May 01, 2020 at 04:25:27PM +0100, John Garry wrote:
>> On 30/04/2020 12:48, Sudeep Holla wrote:
>>> +static int __init smccc_soc_init(void)
>>> +{
>>> +	struct device *dev;
>>> +	int ret, soc_id_rev;
>>> +	struct arm_smccc_res res;
>>> +	static char soc_id_str[8], soc_id_rev_str[12];
>>> +
>>> +	if (arm_smccc_get_version() < ARM_SMCCC_VERSION_1_2)
>>> +		return 0;
>>> +
>>> +	ret = smccc_soc_id_support_check();
>>> +	if (ret)
>>> +		return ret;
>>> +
>>> +	arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_SOC_ID, 0, &res);
>>> +
>>> +	ret = smccc_map_error_codes(res.a0);
>>> +	if (ret)
>>> +		return ret;
>>> +
>>> +	soc_id_version = res.a0;
>>> +
>>> +	arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_SOC_ID, 1, &res);
>>> +
>>> +	ret = smccc_map_error_codes(res.a0);
>>> +	if (ret)
>>> +		return ret;
>>> +
>>> +	soc_id_rev = res.a0;
>>> +
>>> +	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
>>> +	if (!soc_dev_attr)
>>> +		return -ENOMEM;
>>> +
>>> +	sprintf(soc_id_str, "0x%04x", IMP_DEF_SOC_ID(soc_id_version));
>>> +	sprintf(soc_id_rev_str, "0x%08x", soc_id_rev);
>>> +
>>> +	soc_dev_attr->soc_id = soc_id_str;
>>> +	soc_dev_attr->revision = soc_id_rev_str;
>>> +
>>> +	soc_dev = soc_device_register(soc_dev_attr);
>>> +	if (IS_ERR(soc_dev)) {
>>> +		ret = PTR_ERR(soc_dev);
>>> +		goto free_soc;
>>> +	}
>>> +
>>> +	dev = soc_device_to_device(soc_dev);
>>> +
>>
>> Just wondering, what about if the platform already had a SoC driver - now it
>> could have another one, such that we may have multiple sysfs soc devices,
>> right?
>>
> 
> Yes I had a quick look at that.
> 
> 1. Such platform has option not to implement this SOC_ID if it doesn't
>     really require it.

True

> 
> 2. If the firmware starts implementing it on some variants, then we can
>     distinguish them with compatibles and blacklist them from the other
>     SoC driver if having both is an issue
> 
> 3. SoC bus layer supports adding multiple SoC ID driver and it may show
>     up as /sys/devices/soc<n> which may or may not be fine.

Yeah, it's this scenario which I'm concerned about, where some userspace 
expects, for example, soc0 to have a soc id from a known, expected list, 
and now may get something else. However it could be argued then that 
userspace is just too fragile then and there is no read problem here.

  But this
>     happens only if neither [1] nor [2] is done. I am happy to see if there's
>     any solution for this. Any suggestions ?

Not sure, but taking a slight deviation, maybe a way could be found to 
supplement this dev attribute info to other ARM soc drivers.

Cheers,
John

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2020-05-01 16:41 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-30 11:48 [PATCH 0/5] arm/arm64: smccc: Add ARCH_SOC_ID support Sudeep Holla
2020-04-30 11:48 ` [PATCH 1/5] arm/arm64: smccc: Update link to latest SMCCC specification Sudeep Holla
2020-05-01 14:46   ` Steven Price
2020-04-30 11:48 ` [PATCH 2/5] arm/arm64: smccc: Add the definition for SMCCCv1.2 version/error codes Sudeep Holla
2020-05-01 14:46   ` Steven Price
2020-04-30 11:48 ` [PATCH 3/5] arm/arm64: smccc: Drop smccc_version enum and use ARM_SMCCC_VERSION_1_x instead Sudeep Holla
2020-05-01 14:48   ` Steven Price
2020-04-30 11:48 ` [PATCH 4/5] firmware: psci: Add function to fetch SMCCC version Sudeep Holla
2020-04-30 11:48 ` [PATCH 5/5] arm/arm64: smccc: Add ARCH_SOC_ID support Sudeep Holla
2020-05-01 15:07   ` Steven Price
2020-05-01 15:57     ` Sudeep Holla
2020-05-01 15:25   ` John Garry
2020-05-01 16:05     ` Sudeep Holla
2020-05-01 16:40       ` John Garry

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).