
-----Original Message----- From: Lim, Elly Siew Chin elly.siew.chin.lim@intel.com Sent: Tuesday, December 22, 2020 12:50 AM To: u-boot@lists.denx.de Cc: Marek Vasut marex@denx.de; Tan, Ley Foon ley.foon.tan@intel.com; See, Chin Liang chin.liang.see@intel.com; Simon Goldschmidt simon.k.r.goldschmidt@gmail.com; Chee, Tien Fong tien.fong.chee@intel.com; Westergreen, Dalon dalon.westergreen@intel.com; Simon Glass sjg@chromium.org; Gan, Yau Wai yau.wai.gan@intel.com; Lim, Elly Siew Chin elly.siew.chin.lim@intel.com Subject: [v5 07/18] 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
v5
Return error code instead of hang the system if fail to access the secure register.
arch/arm/mach-socfpga/Makefile | 1 + .../mach-socfpga/include/mach/secure_reg_helper.h | 19 +++++ arch/arm/mach-socfpga/secure_reg_helper.c | 97 ++++++++++++++++++++++ 3 files changed, 117 insertions(+) create mode 100644 arch/arm/mach- socfpga/include/mach/secure_reg_helper.h create mode 100644 arch/arm/mach-socfpga/secure_reg_helper.c
diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach- socfpga/Makefile index 0b05283a7a..82b681d870 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 0000000000..d5a11122c7 --- /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 0000000000..d9be45cc97 --- /dev/null +++ b/arch/arm/mach-socfpga/secure_reg_helper.c @@ -0,0 +1,97 @@ +// 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, ®_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, ®_addr);
- if (ret)
return ret;
- args[0] = (u64)reg_addr;
- args[1] = val;
- ret = invoke_smc(INTEL_SIP_SMC_REG_WRITE, args, 2, NULL, 0);
- if (ret)
return ret;
"ret" will have value 0 when success? If yes, then can just "return ret" here directly, doesn't need to check ret.
- return 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, ®_addr);
- if (ret)
return ret;
- args[0] = (u64)reg_addr;
- args[1] = mask;
- args[2] = val;
- ret = invoke_smc(INTEL_SIP_SMC_REG_UPDATE, args, 3, NULL, 0);
- if (ret)
return ret;
- return 0;
Same here.
Regards Ley Foon