1 // SPDX-License-Identifier: GPL-2.0
3 * Xilinx ZynqMP SecureFw Driver.
4 * Copyright (c) 2018 Xilinx Inc.
7 #include <asm/cacheflush.h>
8 #include <linux/device.h>
9 #include <linux/dma-mapping.h>
10 #include <linux/firmware.h>
11 #include <linux/firmware/xlnx-zynqmp.h>
12 #include <linux/init.h>
13 #include <linux/module.h>
14 #include <linux/platform_device.h>
15 #include <linux/of_device.h>
17 #define ZYNQMP_AES_KEY_SIZE 64
19 static u8 key[ZYNQMP_AES_KEY_SIZE] = {0};
20 static dma_addr_t dma_addr;
22 static size_t dma_size;
25 static const struct zynqmp_eemi_ops *eemi_ops;
27 static ssize_t secure_load_store(struct device *dev,
28 struct device_attribute *attr,
29 const char *buf, size_t count)
31 const struct firmware *fw;
32 char image_name[NAME_MAX];
36 if (!eemi_ops || !eemi_ops->secure_image)
39 strncpy(image_name, buf, NAME_MAX);
40 len = strlen(image_name);
41 if (image_name[len - 1] == '\n')
42 image_name[len - 1] = 0;
44 ret = request_firmware(&fw, image_name, dev);
46 dev_err(dev, "Error requesting firmware %s\n", image_name);
52 dma_size = fw->size + ZYNQMP_AES_KEY_SIZE;
54 kbuf = dma_alloc_coherent(dev, dma_size,
55 &dma_addr, GFP_KERNEL);
59 memcpy(kbuf, fw->data, fw->size);
62 memcpy(kbuf + fw->size, key, ZYNQMP_AES_KEY_SIZE);
64 /* To ensure cache coherency */
65 __flush_cache_user_range((unsigned long)kbuf,
66 (unsigned long)kbuf + dma_size);
70 ret = eemi_ops->secure_image(dma_addr, dma_addr + fw->size,
73 ret = eemi_ops->secure_image(dma_addr, 0, &dst);
76 dev_info(dev, "Failed to load secure image \r\n");
79 dev_info(dev, "Verified image at 0x%llx\n", dst);
84 static ssize_t key_show(struct device *dev,
85 struct device_attribute *attr,
88 return snprintf(buf, ZYNQMP_AES_KEY_SIZE + 1, "%s\n", key);
91 static ssize_t key_store(struct device *dev,
92 struct device_attribute *attr,
93 const char *buf, size_t count)
95 memcpy(key, buf, count);
100 static ssize_t secure_load_done_store(struct device *dev,
101 struct device_attribute *attr,
102 const char *buf, size_t count)
107 ret = kstrtouint(buf, 10, &value);
111 dma_free_coherent(dev, dma_size, kbuf, dma_addr);
116 static DEVICE_ATTR_RW(key);
117 static DEVICE_ATTR_WO(secure_load);
118 static DEVICE_ATTR_WO(secure_load_done);
120 static struct attribute *securefw_attrs[] = {
121 &dev_attr_secure_load_done.attr,
122 &dev_attr_secure_load.attr,
127 ATTRIBUTE_GROUPS(securefw);
129 static int securefw_probe(struct platform_device *pdev)
132 struct platform_device *securefw_pdev;
134 eemi_ops = zynqmp_pm_get_eemi_ops();
135 if (IS_ERR(eemi_ops))
136 return PTR_ERR(eemi_ops);
138 securefw_pdev = pdev;
140 securefw_pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
142 ret = of_dma_configure(&securefw_pdev->dev, NULL, true);
144 dev_info(&securefw_pdev->dev, "Cannot setup DMA ops\r\n");
148 ret = sysfs_create_groups(&securefw_pdev->dev.kobj, securefw_groups);
152 dev_info(&securefw_pdev->dev, "securefw probed\r\n");
156 static int securefw_remove(struct platform_device *pdev)
158 sysfs_remove_groups(&pdev->dev.kobj, securefw_groups);
162 static struct platform_driver securefw_driver = {
166 .probe = securefw_probe,
167 .remove = securefw_remove,
170 static struct platform_device *securefw_dev_reg;
172 static int __init zynqmp_secure_init(void)
176 ret = platform_driver_register(&securefw_driver);
180 securefw_dev_reg = platform_device_register_simple("securefw", -1,
182 if (IS_ERR(securefw_dev_reg)) {
183 ret = PTR_ERR(securefw_dev_reg);
184 platform_driver_unregister(&securefw_driver);
190 static void __exit zynqmp_secure_exit(void)
192 platform_device_unregister(securefw_dev_reg);
193 platform_driver_unregister(&securefw_driver);
196 module_init(zynqmp_secure_init);
197 module_exit(zynqmp_secure_exit);