aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorSiew Chin Lim2020-12-24 18:21:02 +0800
committerLey Foon Tan2021-01-15 17:48:36 +0800
commit2e54a1d46c143f12653a44c8485e7d8bfd573b1d (patch)
tree9591c31fb9ed69ba84b1af0346ed7d9e1b970edd /arch
parent313de7335248ff3246e4f2da4e63e50c350a2ac3 (diff)
arm: socfpga: Add secure register access helper functions for SoC 64bits
These secure register access functions allow U-Boot proper running at EL2 (non-secure) to access System Manager's secure registers by calling the ATF's PSCI runtime services (EL3/secure). Signed-off-by: Siew Chin Lim <elly.siew.chin.lim@intel.com> Reviewed-by: Ley Foon Tan <ley.foon.tan@intel.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-socfpga/Makefile1
-rw-r--r--arch/arm/mach-socfpga/include/mach/secure_reg_helper.h19
-rw-r--r--arch/arm/mach-socfpga/secure_reg_helper.c89
3 files changed, 109 insertions, 0 deletions
diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile
index 0b05283a7a1..82b681d870f 100644
--- a/arch/arm/mach-socfpga/Makefile
+++ b/arch/arm/mach-socfpga/Makefile
@@ -73,6 +73,7 @@ obj-y += firewall.o
obj-y += spl_agilex.o
endif
else
+obj-$(CONFIG_SPL_ATF) += secure_reg_helper.o
obj-$(CONFIG_SPL_ATF) += smc_api.o
endif
diff --git a/arch/arm/mach-socfpga/include/mach/secure_reg_helper.h b/arch/arm/mach-socfpga/include/mach/secure_reg_helper.h
new file mode 100644
index 00000000000..d5a11122c72
--- /dev/null
+++ b/arch/arm/mach-socfpga/include/mach/secure_reg_helper.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2020 Intel Corporation <www.intel.com>
+ *
+ */
+
+#ifndef _SECURE_REG_HELPER_H_
+#define _SECURE_REG_HELPER_H_
+
+#define SOCFPGA_SECURE_REG_SYSMGR_SOC64_SDMMC 1
+#define SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC0 2
+#define SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC1 3
+#define SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC2 4
+
+int socfpga_secure_reg_read32(u32 id, u32 *val);
+int socfpga_secure_reg_write32(u32 id, u32 val);
+int socfpga_secure_reg_update32(u32 id, u32 mask, u32 val);
+
+#endif /* _SECURE_REG_HELPER_H_ */
diff --git a/arch/arm/mach-socfpga/secure_reg_helper.c b/arch/arm/mach-socfpga/secure_reg_helper.c
new file mode 100644
index 00000000000..0d4f45f33da
--- /dev/null
+++ b/arch/arm/mach-socfpga/secure_reg_helper.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Intel Corporation <www.intel.com>
+ *
+ */
+
+#include <common.h>
+#include <hang.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/arch/misc.h>
+#include <asm/arch/secure_reg_helper.h>
+#include <asm/arch/smc_api.h>
+#include <asm/arch/system_manager.h>
+#include <linux/errno.h>
+#include <linux/intel-smc.h>
+
+int socfpga_secure_convert_reg_id_to_addr(u32 id, phys_addr_t *reg_addr)
+{
+ switch (id) {
+ case SOCFPGA_SECURE_REG_SYSMGR_SOC64_SDMMC:
+ *reg_addr = socfpga_get_sysmgr_addr() + SYSMGR_SOC64_SDMMC;
+ break;
+ case SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC0:
+ *reg_addr = socfpga_get_sysmgr_addr() + SYSMGR_SOC64_EMAC0;
+ break;
+ case SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC1:
+ *reg_addr = socfpga_get_sysmgr_addr() + SYSMGR_SOC64_EMAC1;
+ break;
+ case SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC2:
+ *reg_addr = socfpga_get_sysmgr_addr() + SYSMGR_SOC64_EMAC2;
+ break;
+ default:
+ return -EADDRNOTAVAIL;
+ }
+ return 0;
+}
+
+int socfpga_secure_reg_read32(u32 id, u32 *val)
+{
+ int ret;
+ u64 ret_arg;
+ u64 args[1];
+
+ phys_addr_t reg_addr;
+ ret = socfpga_secure_convert_reg_id_to_addr(id, &reg_addr);
+ if (ret)
+ return ret;
+
+ args[0] = (u64)reg_addr;
+ ret = invoke_smc(INTEL_SIP_SMC_REG_READ, args, 1, &ret_arg, 1);
+ if (ret)
+ return ret;
+
+ *val = (u32)ret_arg;
+
+ return 0;
+}
+
+int socfpga_secure_reg_write32(u32 id, u32 val)
+{
+ int ret;
+ u64 args[2];
+
+ phys_addr_t reg_addr;
+ ret = socfpga_secure_convert_reg_id_to_addr(id, &reg_addr);
+ if (ret)
+ return ret;
+
+ args[0] = (u64)reg_addr;
+ args[1] = val;
+ return invoke_smc(INTEL_SIP_SMC_REG_WRITE, args, 2, NULL, 0);
+}
+
+int socfpga_secure_reg_update32(u32 id, u32 mask, u32 val)
+{
+ int ret;
+ u64 args[3];
+
+ phys_addr_t reg_addr;
+ ret = socfpga_secure_convert_reg_id_to_addr(id, &reg_addr);
+ if (ret)
+ return ret;
+
+ args[0] = (u64)reg_addr;
+ args[1] = mask;
+ args[2] = val;
+ return invoke_smc(INTEL_SIP_SMC_REG_UPDATE, args, 3, NULL, 0);
+}