diff options
author | Siew Chin Lim | 2020-12-24 18:21:02 +0800 |
---|---|---|
committer | Ley Foon Tan | 2021-01-15 17:48:36 +0800 |
commit | 2e54a1d46c143f12653a44c8485e7d8bfd573b1d (patch) | |
tree | 9591c31fb9ed69ba84b1af0346ed7d9e1b970edd /arch | |
parent | 313de7335248ff3246e4f2da4e63e50c350a2ac3 (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/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/include/mach/secure_reg_helper.h | 19 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/secure_reg_helper.c | 89 |
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, ®_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; + 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, ®_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); +} |