Merge branch 'x86-pti-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / drivers / staging / ccree / ssi_driver.c
1 /*
2  * Copyright (C) 2012-2017 ARM Limited or its affiliates.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, see <http://www.gnu.org/licenses/>.
15  */
16
17 #include <linux/kernel.h>
18 #include <linux/module.h>
19
20 #include <linux/crypto.h>
21 #include <crypto/algapi.h>
22 #include <crypto/aes.h>
23 #include <crypto/sha.h>
24 #include <crypto/aead.h>
25 #include <crypto/authenc.h>
26 #include <crypto/scatterwalk.h>
27 #include <crypto/internal/skcipher.h>
28
29 #include <linux/init.h>
30 #include <linux/moduleparam.h>
31 #include <linux/types.h>
32 #include <linux/random.h>
33 #include <linux/ioport.h>
34 #include <linux/interrupt.h>
35 #include <linux/fcntl.h>
36 #include <linux/poll.h>
37 #include <linux/proc_fs.h>
38 #include <linux/mutex.h>
39 #include <linux/sysctl.h>
40 #include <linux/fs.h>
41 #include <linux/cdev.h>
42 #include <linux/platform_device.h>
43 #include <linux/mm.h>
44 #include <linux/delay.h>
45 #include <linux/dma-mapping.h>
46 #include <linux/dmapool.h>
47 #include <linux/list.h>
48 #include <linux/slab.h>
49 #include <linux/spinlock.h>
50 #include <linux/pm.h>
51
52 /* cache.h required for L1_CACHE_ALIGN() and cache_line_size() */
53 #include <linux/cache.h>
54 #include <linux/io.h>
55 #include <linux/uaccess.h>
56 #include <linux/pagemap.h>
57 #include <linux/sched.h>
58 #include <linux/random.h>
59 #include <linux/of.h>
60 #include <linux/clk.h>
61 #include <linux/of_address.h>
62
63 #include "ssi_config.h"
64 #include "ssi_driver.h"
65 #include "ssi_request_mgr.h"
66 #include "ssi_buffer_mgr.h"
67 #include "ssi_sysfs.h"
68 #include "ssi_cipher.h"
69 #include "ssi_aead.h"
70 #include "ssi_hash.h"
71 #include "ssi_ivgen.h"
72 #include "ssi_sram_mgr.h"
73 #include "ssi_pm.h"
74 #include "ssi_fips.h"
75
76 #ifdef DX_DUMP_BYTES
77 void dump_byte_array(const char *name, const u8 *buf, size_t len)
78 {
79         char prefix[NAME_LEN];
80
81         if (!buf)
82                 return;
83
84         snprintf(prefix, sizeof(prefix), "%s[%lu]: ", name, len);
85
86         print_hex_dump(KERN_DEBUG, prefix, DUMP_PREFIX_ADDRESS, 16, 1, len,
87                        false);
88 }
89 #endif
90
91 static irqreturn_t cc_isr(int irq, void *dev_id)
92 {
93         struct ssi_drvdata *drvdata = (struct ssi_drvdata *)dev_id;
94         struct device *dev = drvdata_to_dev(drvdata);
95         u32 irr;
96         u32 imr;
97
98         /* STAT_OP_TYPE_GENERIC STAT_PHASE_0: Interrupt */
99
100         /* read the interrupt status */
101         irr = cc_ioread(drvdata, CC_REG(HOST_IRR));
102         dev_dbg(dev, "Got IRR=0x%08X\n", irr);
103         if (unlikely(irr == 0)) { /* Probably shared interrupt line */
104                 dev_err(dev, "Got interrupt with empty IRR\n");
105                 return IRQ_NONE;
106         }
107         imr = cc_ioread(drvdata, CC_REG(HOST_IMR));
108
109         /* clear interrupt - must be before processing events */
110         cc_iowrite(drvdata, CC_REG(HOST_ICR), irr);
111
112         drvdata->irq = irr;
113         /* Completion interrupt - most probable */
114         if (likely((irr & SSI_COMP_IRQ_MASK) != 0)) {
115                 /* Mask AXI completion interrupt - will be unmasked in Deferred service handler */
116                 cc_iowrite(drvdata, CC_REG(HOST_IMR), imr | SSI_COMP_IRQ_MASK);
117                 irr &= ~SSI_COMP_IRQ_MASK;
118                 complete_request(drvdata);
119         }
120 #ifdef CC_SUPPORT_FIPS
121         /* TEE FIPS interrupt */
122         if (likely((irr & SSI_GPR0_IRQ_MASK) != 0)) {
123                 /* Mask interrupt - will be unmasked in Deferred service handler */
124                 cc_iowrite(drvdata, CC_REG(HOST_IMR), imr | SSI_GPR0_IRQ_MASK);
125                 irr &= ~SSI_GPR0_IRQ_MASK;
126                 fips_handler(drvdata);
127         }
128 #endif
129         /* AXI error interrupt */
130         if (unlikely((irr & SSI_AXI_ERR_IRQ_MASK) != 0)) {
131                 u32 axi_err;
132
133                 /* Read the AXI error ID */
134                 axi_err = cc_ioread(drvdata, CC_REG(AXIM_MON_ERR));
135                 dev_dbg(dev, "AXI completion error: axim_mon_err=0x%08X\n",
136                         axi_err);
137
138                 irr &= ~SSI_AXI_ERR_IRQ_MASK;
139         }
140
141         if (unlikely(irr != 0)) {
142                 dev_dbg(dev, "IRR includes unknown cause bits (0x%08X)\n",
143                         irr);
144                 /* Just warning */
145         }
146
147         return IRQ_HANDLED;
148 }
149
150 int init_cc_regs(struct ssi_drvdata *drvdata, bool is_probe)
151 {
152         unsigned int val, cache_params;
153         struct device *dev = drvdata_to_dev(drvdata);
154
155         /* Unmask all AXI interrupt sources AXI_CFG1 register */
156         val = cc_ioread(drvdata, CC_REG(AXIM_CFG));
157         cc_iowrite(drvdata, CC_REG(AXIM_CFG), val & ~SSI_AXI_IRQ_MASK);
158         dev_dbg(dev, "AXIM_CFG=0x%08X\n",
159                 cc_ioread(drvdata, CC_REG(AXIM_CFG)));
160
161         /* Clear all pending interrupts */
162         val = cc_ioread(drvdata, CC_REG(HOST_IRR));
163         dev_dbg(dev, "IRR=0x%08X\n", val);
164         cc_iowrite(drvdata, CC_REG(HOST_ICR), val);
165
166         /* Unmask relevant interrupt cause */
167         val = (unsigned int)(~(SSI_COMP_IRQ_MASK | SSI_AXI_ERR_IRQ_MASK |
168                                SSI_GPR0_IRQ_MASK));
169         cc_iowrite(drvdata, CC_REG(HOST_IMR), val);
170
171 #ifdef DX_HOST_IRQ_TIMER_INIT_VAL_REG_OFFSET
172 #ifdef DX_IRQ_DELAY
173         /* Set CC IRQ delay */
174         cc_iowrite(drvdata, CC_REG(HOST_IRQ_TIMER_INIT_VAL), DX_IRQ_DELAY);
175 #endif
176         if (cc_ioread(drvdata, CC_REG(HOST_IRQ_TIMER_INIT_VAL)) > 0) {
177                 dev_dbg(dev, "irq_delay=%d CC cycles\n",
178                         cc_ioread(drvdata, CC_REG(HOST_IRQ_TIMER_INIT_VAL)));
179         }
180 #endif
181
182         cache_params = (drvdata->coherent ? CC_COHERENT_CACHE_PARAMS : 0x0);
183
184         val = cc_ioread(drvdata, CC_REG(AXIM_CACHE_PARAMS));
185
186         if (is_probe)
187                 dev_info(dev, "Cache params previous: 0x%08X\n", val);
188
189         cc_iowrite(drvdata, CC_REG(AXIM_CACHE_PARAMS), cache_params);
190         val = cc_ioread(drvdata, CC_REG(AXIM_CACHE_PARAMS));
191
192         if (is_probe)
193                 dev_info(dev, "Cache params current: 0x%08X (expect: 0x%08X)\n",
194                          val, cache_params);
195
196         return 0;
197 }
198
199 static int init_cc_resources(struct platform_device *plat_dev)
200 {
201         struct resource *req_mem_cc_regs = NULL;
202         void __iomem *cc_base = NULL;
203         struct ssi_drvdata *new_drvdata;
204         struct device *dev = &plat_dev->dev;
205         struct device_node *np = dev->of_node;
206         u32 signature_val;
207         dma_addr_t dma_mask;
208         int rc = 0;
209
210         new_drvdata = devm_kzalloc(dev, sizeof(*new_drvdata), GFP_KERNEL);
211         if (!new_drvdata)
212                 return -ENOMEM;
213
214         platform_set_drvdata(plat_dev, new_drvdata);
215         new_drvdata->plat_dev = plat_dev;
216
217         new_drvdata->clk = of_clk_get(np, 0);
218         new_drvdata->coherent = of_dma_is_coherent(np);
219
220         /* Get device resources */
221         /* First CC registers space */
222         req_mem_cc_regs = platform_get_resource(plat_dev, IORESOURCE_MEM, 0);
223         /* Map registers space */
224         new_drvdata->cc_base = devm_ioremap_resource(dev, req_mem_cc_regs);
225         if (IS_ERR(new_drvdata->cc_base)) {
226                 dev_err(dev, "Failed to ioremap registers");
227                 return PTR_ERR(new_drvdata->cc_base);
228         }
229
230         dev_dbg(dev, "Got MEM resource (%s): %pR\n", req_mem_cc_regs->name,
231                 req_mem_cc_regs);
232         dev_dbg(dev, "CC registers mapped from %pa to 0x%p\n",
233                 &req_mem_cc_regs->start, new_drvdata->cc_base);
234
235         cc_base = new_drvdata->cc_base;
236
237         /* Then IRQ */
238         new_drvdata->irq = platform_get_irq(plat_dev, 0);
239         if (new_drvdata->irq < 0) {
240                 dev_err(dev, "Failed getting IRQ resource\n");
241                 return new_drvdata->irq;
242         }
243
244         rc = devm_request_irq(dev, new_drvdata->irq, cc_isr,
245                               IRQF_SHARED, "arm_cc7x", new_drvdata);
246         if (rc) {
247                 dev_err(dev, "Could not register to interrupt %d\n",
248                         new_drvdata->irq);
249                 return rc;
250         }
251         dev_dbg(dev, "Registered to IRQ: %d\n", new_drvdata->irq);
252
253         if (!plat_dev->dev.dma_mask)
254                 plat_dev->dev.dma_mask = &plat_dev->dev.coherent_dma_mask;
255
256         dma_mask = (dma_addr_t)(DMA_BIT_MASK(DMA_BIT_MASK_LEN));
257         while (dma_mask > 0x7fffffffUL) {
258                 if (dma_supported(&plat_dev->dev, dma_mask)) {
259                         rc = dma_set_coherent_mask(&plat_dev->dev, dma_mask);
260                         if (!rc)
261                                 break;
262                 }
263                 dma_mask >>= 1;
264         }
265
266         if (rc) {
267                 dev_err(dev, "Failed in dma_set_mask, mask=%par\n",
268                         &dma_mask);
269                 return rc;
270         }
271
272         rc = cc_clk_on(new_drvdata);
273         if (rc) {
274                 dev_err(dev, "Failed to enable clock");
275                 return rc;
276         }
277
278         /* Verify correct mapping */
279         signature_val = cc_ioread(new_drvdata, CC_REG(HOST_SIGNATURE));
280         if (signature_val != DX_DEV_SIGNATURE) {
281                 dev_err(dev, "Invalid CC signature: SIGNATURE=0x%08X != expected=0x%08X\n",
282                         signature_val, (u32)DX_DEV_SIGNATURE);
283                 rc = -EINVAL;
284                 goto post_clk_err;
285         }
286         dev_dbg(dev, "CC SIGNATURE=0x%08X\n", signature_val);
287
288         /* Display HW versions */
289         dev_info(dev, "ARM CryptoCell %s Driver: HW version 0x%08X, Driver version %s\n",
290                  SSI_DEV_NAME_STR,
291                  cc_ioread(new_drvdata, CC_REG(HOST_VERSION)),
292                  DRV_MODULE_VERSION);
293
294         rc = init_cc_regs(new_drvdata, true);
295         if (unlikely(rc != 0)) {
296                 dev_err(dev, "init_cc_regs failed\n");
297                 goto post_clk_err;
298         }
299
300 #ifdef ENABLE_CC_SYSFS
301         rc = ssi_sysfs_init(&dev->kobj, new_drvdata);
302         if (unlikely(rc != 0)) {
303                 dev_err(dev, "init_stat_db failed\n");
304                 goto post_regs_err;
305         }
306 #endif
307
308         rc = ssi_fips_init(new_drvdata);
309         if (unlikely(rc != 0)) {
310                 dev_err(dev, "SSI_FIPS_INIT failed 0x%x\n", rc);
311                 goto post_sysfs_err;
312         }
313         rc = ssi_sram_mgr_init(new_drvdata);
314         if (unlikely(rc != 0)) {
315                 dev_err(dev, "ssi_sram_mgr_init failed\n");
316                 goto post_fips_init_err;
317         }
318
319         new_drvdata->mlli_sram_addr =
320                 ssi_sram_mgr_alloc(new_drvdata, MAX_MLLI_BUFF_SIZE);
321         if (unlikely(new_drvdata->mlli_sram_addr == NULL_SRAM_ADDR)) {
322                 dev_err(dev, "Failed to alloc MLLI Sram buffer\n");
323                 rc = -ENOMEM;
324                 goto post_sram_mgr_err;
325         }
326
327         rc = request_mgr_init(new_drvdata);
328         if (unlikely(rc != 0)) {
329                 dev_err(dev, "request_mgr_init failed\n");
330                 goto post_sram_mgr_err;
331         }
332
333         rc = ssi_buffer_mgr_init(new_drvdata);
334         if (unlikely(rc != 0)) {
335                 dev_err(dev, "buffer_mgr_init failed\n");
336                 goto post_req_mgr_err;
337         }
338
339         rc = ssi_power_mgr_init(new_drvdata);
340         if (unlikely(rc != 0)) {
341                 dev_err(dev, "ssi_power_mgr_init failed\n");
342                 goto post_buf_mgr_err;
343         }
344
345         rc = ssi_ivgen_init(new_drvdata);
346         if (unlikely(rc != 0)) {
347                 dev_err(dev, "ssi_ivgen_init failed\n");
348                 goto post_power_mgr_err;
349         }
350
351         /* Allocate crypto algs */
352         rc = ssi_ablkcipher_alloc(new_drvdata);
353         if (unlikely(rc != 0)) {
354                 dev_err(dev, "ssi_ablkcipher_alloc failed\n");
355                 goto post_ivgen_err;
356         }
357
358         /* hash must be allocated before aead since hash exports APIs */
359         rc = ssi_hash_alloc(new_drvdata);
360         if (unlikely(rc != 0)) {
361                 dev_err(dev, "ssi_hash_alloc failed\n");
362                 goto post_cipher_err;
363         }
364
365         rc = ssi_aead_alloc(new_drvdata);
366         if (unlikely(rc != 0)) {
367                 dev_err(dev, "ssi_aead_alloc failed\n");
368                 goto post_hash_err;
369         }
370
371         /* If we got here and FIPS mode is enabled
372          * it means all FIPS test passed, so let TEE
373          * know we're good.
374          */
375         cc_set_ree_fips_status(new_drvdata, true);
376
377         return 0;
378
379 post_hash_err:
380         ssi_hash_free(new_drvdata);
381 post_cipher_err:
382         ssi_ablkcipher_free(new_drvdata);
383 post_ivgen_err:
384         ssi_ivgen_fini(new_drvdata);
385 post_power_mgr_err:
386         ssi_power_mgr_fini(new_drvdata);
387 post_buf_mgr_err:
388          ssi_buffer_mgr_fini(new_drvdata);
389 post_req_mgr_err:
390         request_mgr_fini(new_drvdata);
391 post_sram_mgr_err:
392         ssi_sram_mgr_fini(new_drvdata);
393 post_fips_init_err:
394         ssi_fips_fini(new_drvdata);
395 post_sysfs_err:
396 #ifdef ENABLE_CC_SYSFS
397         ssi_sysfs_fini();
398 #endif
399 post_regs_err:
400         fini_cc_regs(new_drvdata);
401 post_clk_err:
402         cc_clk_off(new_drvdata);
403         return rc;
404 }
405
406 void fini_cc_regs(struct ssi_drvdata *drvdata)
407 {
408         /* Mask all interrupts */
409         cc_iowrite(drvdata, CC_REG(HOST_IMR), 0xFFFFFFFF);
410 }
411
412 static void cleanup_cc_resources(struct platform_device *plat_dev)
413 {
414         struct ssi_drvdata *drvdata =
415                 (struct ssi_drvdata *)platform_get_drvdata(plat_dev);
416
417         ssi_aead_free(drvdata);
418         ssi_hash_free(drvdata);
419         ssi_ablkcipher_free(drvdata);
420         ssi_ivgen_fini(drvdata);
421         ssi_power_mgr_fini(drvdata);
422         ssi_buffer_mgr_fini(drvdata);
423         request_mgr_fini(drvdata);
424         ssi_sram_mgr_fini(drvdata);
425         ssi_fips_fini(drvdata);
426 #ifdef ENABLE_CC_SYSFS
427         ssi_sysfs_fini();
428 #endif
429         fini_cc_regs(drvdata);
430         cc_clk_off(drvdata);
431 }
432
433 int cc_clk_on(struct ssi_drvdata *drvdata)
434 {
435         struct clk *clk = drvdata->clk;
436         int rc;
437
438         if (IS_ERR(clk))
439                 /* Not all devices have a clock associated with CCREE  */
440                 return 0;
441
442         rc = clk_prepare_enable(clk);
443         if (rc)
444                 return rc;
445
446         return 0;
447 }
448
449 void cc_clk_off(struct ssi_drvdata *drvdata)
450 {
451         struct clk *clk = drvdata->clk;
452
453         if (IS_ERR(clk))
454                 /* Not all devices have a clock associated with CCREE */
455                 return;
456
457         clk_disable_unprepare(clk);
458 }
459
460 static int cc7x_probe(struct platform_device *plat_dev)
461 {
462         int rc;
463         struct device *dev = &plat_dev->dev;
464 #if defined(CONFIG_ARM) && defined(CC_DEBUG)
465         u32 ctr, cacheline_size;
466
467         asm volatile("mrc p15, 0, %0, c0, c0, 1" : "=r" (ctr));
468         cacheline_size =  4 << ((ctr >> 16) & 0xf);
469         dev_dbg(dev, "CP15(L1_CACHE_BYTES) = %u , Kconfig(L1_CACHE_BYTES) = %u\n",
470                 cacheline_size, L1_CACHE_BYTES);
471
472         asm volatile("mrc p15, 0, %0, c0, c0, 0" : "=r" (ctr));
473         dev_dbg(dev, "Main ID register (MIDR): Implementer 0x%02X, Arch 0x%01X, Part 0x%03X, Rev r%dp%d\n",
474                 (ctr >> 24), (ctr >> 16) & 0xF, (ctr >> 4) & 0xFFF,
475                 (ctr >> 20) & 0xF, ctr & 0xF);
476 #endif
477
478         /* Map registers space */
479         rc = init_cc_resources(plat_dev);
480         if (rc != 0)
481                 return rc;
482
483         dev_info(dev, "ARM ccree device initialized\n");
484
485         return 0;
486 }
487
488 static int cc7x_remove(struct platform_device *plat_dev)
489 {
490         struct device *dev = &plat_dev->dev;
491
492         dev_dbg(dev, "Releasing cc7x resources...\n");
493
494         cleanup_cc_resources(plat_dev);
495
496         dev_info(dev, "ARM ccree device terminated\n");
497
498         return 0;
499 }
500
501 #if defined(CONFIG_PM_RUNTIME) || defined(CONFIG_PM_SLEEP)
502 static const struct dev_pm_ops arm_cc7x_driver_pm = {
503         SET_RUNTIME_PM_OPS(ssi_power_mgr_runtime_suspend, ssi_power_mgr_runtime_resume, NULL)
504 };
505 #endif
506
507 #if defined(CONFIG_PM_RUNTIME) || defined(CONFIG_PM_SLEEP)
508 #define DX_DRIVER_RUNTIME_PM    (&arm_cc7x_driver_pm)
509 #else
510 #define DX_DRIVER_RUNTIME_PM    NULL
511 #endif
512
513 #ifdef CONFIG_OF
514 static const struct of_device_id arm_cc7x_dev_of_match[] = {
515         {.compatible = "arm,cryptocell-712-ree"},
516         {}
517 };
518 MODULE_DEVICE_TABLE(of, arm_cc7x_dev_of_match);
519 #endif
520
521 static struct platform_driver cc7x_driver = {
522         .driver = {
523                    .name = "cc7xree",
524 #ifdef CONFIG_OF
525                    .of_match_table = arm_cc7x_dev_of_match,
526 #endif
527                    .pm = DX_DRIVER_RUNTIME_PM,
528         },
529         .probe = cc7x_probe,
530         .remove = cc7x_remove,
531 };
532 module_platform_driver(cc7x_driver);
533
534 /* Module description */
535 MODULE_DESCRIPTION("ARM TrustZone CryptoCell REE Driver");
536 MODULE_VERSION(DRV_MODULE_VERSION);
537 MODULE_AUTHOR("ARM");
538 MODULE_LICENSE("GPL v2");