[PATCH v4 11/21] misc: altera_sysmgr: Add Altera System Manager driver

chee.hong.ang at intel.com chee.hong.ang at intel.com
Mon Mar 9 10:07:12 CET 2020


From: Chee Hong Ang <chee.hong.ang at intel.com>

This driver (misc uclass) handle the read/write access to
System Manager. For 64 bits platforms, processor needs to be
in secure mode to has write access to most of the System Manager's
registers (except boot scratch registers). When the processor is
running in EL2 (non-secure), this driver will invoke the SMC call
to ATF to perform write access to the System Manager's registers.
All other drivers that require access to System Manager should
go through this driver.

Signed-off-by: Chee Hong Ang <chee.hong.ang at intel.com>
---
 drivers/misc/Makefile        |   1 +
 drivers/misc/altera_sysmgr.c | 115 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 116 insertions(+)
 create mode 100644 drivers/misc/altera_sysmgr.c

diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 2b843de..9fa2411 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -29,6 +29,7 @@ endif
 endif
 obj-$(CONFIG_ALI152X) += ali512x.o
 obj-$(CONFIG_ALTERA_SYSID) += altera_sysid.o
+obj-$(CONFIG_ARCH_SOCFPGA) += altera_sysmgr.o
 obj-$(CONFIG_ATSHA204A) += atsha204a-i2c.o
 obj-$(CONFIG_CBMEM_CONSOLE) += cbmem_console.o
 obj-$(CONFIG_DS4510)  += ds4510.o
diff --git a/drivers/misc/altera_sysmgr.c b/drivers/misc/altera_sysmgr.c
new file mode 100644
index 0000000..b36ecae
--- /dev/null
+++ b/drivers/misc/altera_sysmgr.c
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Intel Corporation <www.intel.com>
+ */
+
+#include <common.h>
+#include <command.h>
+#include <dm.h>
+#include <errno.h>
+#include <misc.h>
+#include <asm/io.h>
+#include <asm/arch/misc.h>
+#include <linux/intel-smc.h>
+
+#define IS_OUT_OF_SYSMGR(addr, range) ((addr) > (range))
+
+struct altera_sysmgr_priv {
+	fdt_addr_t base_addr;
+	fdt_addr_t base_size;
+};
+
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF)
+static int secure_write32(u32 val, fdt_addr_t addr)
+{
+	int ret;
+	u64 args[2];
+
+	args[0] = (u64)addr;
+	args[1] = val;
+	ret = invoke_smc(INTEL_SIP_SMC_REG_WRITE, args, 2, NULL, 0);
+	if (ret)
+		return -EIO;
+
+	return 0;
+}
+#endif
+
+static int write32(u32 val, fdt_addr_t addr)
+{
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF)
+	return secure_write32(val, addr);
+#else
+	writel(val, addr);
+
+	return 0;
+#endif
+}
+
+static int altera_sysmgr_read(struct udevice *dev,
+			     int offset, void *buf, int size)
+{
+	struct altera_sysmgr_priv *priv = dev_get_priv(dev);
+	fdt_addr_t addr = priv->base_addr + offset;
+
+	if (IS_OUT_OF_SYSMGR(addr, priv->base_addr + priv->base_size - size))
+		return -EINVAL;
+
+	if (size != sizeof(u32))
+		return -EIO;
+
+	*(u32 *)buf = readl(addr);
+
+	return 0;
+}
+
+static int altera_sysmgr_write(struct udevice *dev, int offset,
+				const void *buf, int size)
+{
+	struct altera_sysmgr_priv *priv = dev_get_priv(dev);
+	fdt_addr_t addr = priv->base_addr + offset;
+
+	if (IS_OUT_OF_SYSMGR(addr, priv->base_addr + priv->base_size - size))
+		return -EINVAL;
+
+	if (size != sizeof(u32))
+		return -EIO;
+
+	return write32(*(u32 *)buf, addr);
+}
+
+static int altera_sysmgr_probe(struct udevice *dev)
+{
+	struct altera_sysmgr_priv *priv = dev_get_priv(dev);
+	fdt_addr_t addr;
+	fdt_size_t size;
+
+	addr = ofnode_get_addr_size_index(dev_ofnode(dev), 0, &size);
+
+	if (addr == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	priv->base_addr = addr;
+	priv->base_size = size;
+
+	return 0;
+}
+
+static const struct misc_ops altera_sysmgr_ops = {
+	.read = altera_sysmgr_read,
+	.write = altera_sysmgr_write,
+};
+
+static const struct udevice_id altera_sysmgr_ids[] = {
+	{ .compatible = "altr,sys-mgr" },
+	{}
+};
+
+U_BOOT_DRIVER(altera_sysmgr) = {
+	.name	= "altr,sys-mgr",
+	.id	= UCLASS_MISC,
+	.of_match = altera_sysmgr_ids,
+	.priv_auto_alloc_size = sizeof(struct altera_sysmgr_priv),
+	.probe = altera_sysmgr_probe,
+	.ops	= &altera_sysmgr_ops,
+};
-- 
2.7.4



More information about the U-Boot mailing list