fc48884cd1797d35930bf6c4a945461c0af9c0cf
[openwrt/staging/mkresin.git] /
1 From 03ec635be0eb1c1b63b1f631938d41b379dad637 Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Horia=20Geant=C4=83?= <horia.geanta@nxp.com>
3 Date: Mon, 30 Sep 2019 00:22:09 +0300
4 Subject: [PATCH] MLKU-38-3 crypto: caam - add SNVS / SECVIO support
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 This is a squash of the following i.MX BSP commits
10 (rel_imx_4.19.35_1.1.0_rc2)
11
12 1. 8f6a17b41917 ("ENGR00289885 [iMX6Q] Add Secure Memory and SECVIO support.")
13 2. 8433c811e97a ("MLK-9710-18 snvs - make SECVIO module device tree correct")
14 3. 35bbc34e996b ("MLK-9769-23 Replace SECVIO of_irq_to_resource() with irq_of_parse_and_map()")
15 4. 3ac6edcd92d4 ("MLK-11360-01 crypto: caam_snvs: add snvs clock management")
16 5. 9d9ca7a03e3b ("MLK-11922 i.mx6: Linux 3.14.28 CAAM & SNVS enabled by default. JTAG, DS-5 attachment causes exceptions")
17 6. fcdaabf1bba2 ("MLK-17412-01: Fix secvio driver to have same driver name as DTS")
18
19 Signed-off-by: Dan Douglass <dan.douglass@nxp.com>
20 Signed-off-by: Victoria Milhoan <vicki.milhoan@freescale.com>
21 Signed-off-by: Steve Cornelius <steve.cornelius@nxp.com>
22 Signed-off-by: Fugang Duan <andy.duan@nxp.com>
23 Signed-off-by: Franck LENORMAND <franck.lenormand@nxp.com>
24
25 that have been reworked:
26
27 1.
28 -make SM depend on JR
29 -enable SM, SECVIO only on i.MX SoCs
30 -fix resource leak - add off_node_put() where needed
31
32 Split commit in three:
33 - SNVS/SECVIO driver
34 - Secure Memory driver
35 - DT changes
36
37 3.
38 JR changes dropped - no longer needed, already upstream in
39 commit 549077d7d86a1 ("crypto: caam - check irq_of_parse_and_map for errors")
40
41 4.
42 Split the patch in two:
43 -DT bindings changes
44 -driver changes
45
46 5.
47 Fixed conflicts in imx7d.dtsi - added caam_sm and irq_sec_vio nodes.
48
49 Split commit in 3:
50 -SECVIO/SNVS driver changes
51 -SECVIO/SNVS DT changes
52 -Secure Memory DT changes
53
54 Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
55 ---
56 drivers/crypto/caam/Kconfig | 7 +
57 drivers/crypto/caam/Makefile | 1 +
58 drivers/crypto/caam/ctrl.c | 3 -
59 drivers/crypto/caam/intern.h | 4 +-
60 drivers/crypto/caam/secvio.c | 342 +++++++++++++++++++++++++++++++++++++++++
61 drivers/crypto/caam/secvio.h | 69 +++++++++
62 drivers/crypto/caam/snvsregs.h | 239 ++++++++++++++++++++++++++++
63 7 files changed, 660 insertions(+), 5 deletions(-)
64 create mode 100644 drivers/crypto/caam/secvio.c
65 create mode 100644 drivers/crypto/caam/secvio.h
66 create mode 100644 drivers/crypto/caam/snvsregs.h
67
68 --- a/drivers/crypto/caam/Kconfig
69 +++ b/drivers/crypto/caam/Kconfig
70 @@ -156,6 +156,13 @@ config CRYPTO_DEV_FSL_CAAM_RNG_TEST
71 caam RNG. This test is several minutes long and executes
72 just before the RNG is registered with the hw_random API.
73
74 +config CRYPTO_DEV_FSL_CAAM_SECVIO
75 + tristate "CAAM/SNVS Security Violation Handler (EXPERIMENTAL)"
76 + help
77 + Enables installation of an interrupt handler with registrable
78 + handler functions which can be specified to act on the consequences
79 + of a security violation.
80 +
81 endif # CRYPTO_DEV_FSL_CAAM_JR
82
83 endif # CRYPTO_DEV_FSL_CAAM
84 --- a/drivers/crypto/caam/Makefile
85 +++ b/drivers/crypto/caam/Makefile
86 @@ -21,6 +21,7 @@ caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRY
87 caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API) += caamhash.o
88 caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API) += caamrng.o
89 caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API) += caampkc.o pkc_desc.o
90 +caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO) += secvio.o
91
92 caam-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) += qi.o
93 ifneq ($(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI),)
94 --- a/drivers/crypto/caam/ctrl.c
95 +++ b/drivers/crypto/caam/ctrl.c
96 @@ -719,9 +719,6 @@ iomap_ctrl:
97 BLOCK_OFFSET * DECO_BLOCK_NUMBER
98 );
99
100 - /* Get the IRQ of the controller (for security violations only) */
101 - ctrlpriv->secvio_irq = irq_of_parse_and_map(nprop, 0);
102 -
103 if (!reg_access)
104 goto set_dma_mask;
105
106 --- a/drivers/crypto/caam/intern.h
107 +++ b/drivers/crypto/caam/intern.h
108 @@ -66,6 +66,7 @@ struct caam_drv_private_jr {
109 * Driver-private storage for a single CAAM block instance
110 */
111 struct caam_drv_private {
112 +
113 /* Physical-presence section */
114 struct caam_ctrl __iomem *ctrl; /* controller region */
115 struct caam_deco __iomem *deco; /* DECO/CCB views */
116 @@ -83,8 +84,7 @@ struct caam_drv_private {
117 u8 qi_present; /* Nonzero if QI present in device */
118 u8 mc_en; /* Nonzero if MC f/w is active */
119 u8 scu_en; /* Nonzero if SCU f/w is active */
120 -+ u8 optee_en; /* Nonzero if OP-TEE f/w is active */
121 - int secvio_irq; /* Security violation interrupt number */
122 + u8 optee_en; /* Nonzero if OP-TEE f/w is active */
123 int virt_en; /* Virtualization enabled in CAAM */
124 int era; /* CAAM Era (internal HW revision) */
125
126 --- /dev/null
127 +++ b/drivers/crypto/caam/secvio.c
128 @@ -0,0 +1,342 @@
129 +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
130 +/*
131 + * SNVS Security Violation Handler
132 + *
133 + * Copyright 2012-2016 Freescale Semiconductor, Inc.
134 + * Copyright 2017-2019 NXP
135 + */
136 +
137 +#include "compat.h"
138 +#include "secvio.h"
139 +#include "regs.h"
140 +#include "intern.h"
141 +#include <linux/of.h>
142 +#include <linux/of_irq.h>
143 +#include <linux/of_address.h>
144 +
145 +/* The driver is matched with node caam_snvs to get regmap
146 + * It will then retrieve interruption and tamper alarm configuration from
147 + * node caam-secvio searching for the compat string "fsl,imx6q-caam-secvio"
148 + */
149 +#define DRIVER_NAME "caam-snvs"
150 +
151 +/*
152 + * These names are associated with each violation handler.
153 + * The source names were taken from MX6, and are based on recommendations
154 + * for most common SoCs.
155 + */
156 +static const u8 *violation_src_name[] = {
157 + "CAAM Internal Security Violation",
158 + "JTAG Alarm",
159 + "Watchdog",
160 + "(reserved)",
161 + "External Boot",
162 + "External Tamper Detect",
163 +};
164 +
165 +/* These names help describe security monitor state for the console */
166 +static const u8 *snvs_ssm_state_name[] = {
167 + "init",
168 + "hard fail",
169 + "(undef:2)",
170 + "soft fail",
171 + "(undef:4)",
172 + "(undef:5)",
173 + "(undef:6)",
174 + "(undef:7)",
175 + "transition",
176 + "check",
177 + "(undef:10)",
178 + "non-secure",
179 + "(undef:12)",
180 + "trusted",
181 + "(undef:14)",
182 + "secure",
183 +};
184 +
185 +/* Top-level security violation interrupt */
186 +static irqreturn_t snvs_secvio_interrupt(int irq, void *snvsdev)
187 +{
188 + struct device *dev = snvsdev;
189 + struct snvs_secvio_drv_private *svpriv = dev_get_drvdata(dev);
190 +
191 + clk_enable(svpriv->clk);
192 + /* Check the HP secvio status register */
193 + svpriv->irqcause = rd_reg32(&svpriv->svregs->hp.secvio_status) &
194 + HP_SECVIOST_SECVIOMASK;
195 +
196 + if (!svpriv->irqcause) {
197 + clk_disable(svpriv->clk);
198 + return IRQ_NONE;
199 + }
200 +
201 + /* Now ACK cause */
202 + clrsetbits_32(&svpriv->svregs->hp.secvio_status, 0, svpriv->irqcause);
203 +
204 + /* And run deferred service */
205 + preempt_disable();
206 + tasklet_schedule(&svpriv->irqtask[smp_processor_id()]);
207 + preempt_enable();
208 +
209 + clk_disable(svpriv->clk);
210 +
211 + return IRQ_HANDLED;
212 +}
213 +
214 +/* Deferred service handler. Tasklet arg is simply the SNVS dev */
215 +static void snvs_secvio_dispatch(unsigned long indev)
216 +{
217 + struct device *dev = (struct device *)indev;
218 + struct snvs_secvio_drv_private *svpriv = dev_get_drvdata(dev);
219 + unsigned long flags;
220 + int i;
221 +
222 +
223 + /* Look through stored causes, call each handler if exists */
224 + for (i = 0; i < MAX_SECVIO_SOURCES; i++)
225 + if (svpriv->irqcause & (1 << i)) {
226 + spin_lock_irqsave(&svpriv->svlock, flags);
227 + svpriv->intsrc[i].handler(dev, i,
228 + svpriv->intsrc[i].ext);
229 + spin_unlock_irqrestore(&svpriv->svlock, flags);
230 + };
231 +
232 + /* Re-enable now-serviced interrupts */
233 + clrsetbits_32(&svpriv->svregs->hp.secvio_intcfg, 0, svpriv->irqcause);
234 +}
235 +
236 +/*
237 + * Default cause handler, used in lieu of an application-defined handler.
238 + * All it does at this time is print a console message. It could force a halt.
239 + */
240 +static void snvs_secvio_default(struct device *dev, u32 cause, void *ext)
241 +{
242 + struct snvs_secvio_drv_private *svpriv = dev_get_drvdata(dev);
243 +
244 + dev_err(dev, "Unhandled Security Violation Interrupt %d = %s\n",
245 + cause, svpriv->intsrc[cause].intname);
246 +}
247 +
248 +/*
249 + * Install an application-defined handler for a specified cause
250 + * Arguments:
251 + * - dev points to SNVS-owning device
252 + * - cause interrupt source cause
253 + * - handler application-defined handler, gets called with dev
254 + * source cause, and locally-defined handler argument
255 + * - cause_description points to a string to override the default cause
256 + * name, this can be used as an alternate for error
257 + * messages and such. If left NULL, the default
258 + * description string is used.
259 + * - ext pointer to any extra data needed by the handler.
260 + */
261 +int snvs_secvio_install_handler(struct device *dev, enum secvio_cause cause,
262 + void (*handler)(struct device *dev, u32 cause,
263 + void *ext),
264 + u8 *cause_description, void *ext)
265 +{
266 + unsigned long flags;
267 + struct snvs_secvio_drv_private *svpriv;
268 +
269 + svpriv = dev_get_drvdata(dev);
270 +
271 + if ((handler == NULL) || (cause > SECVIO_CAUSE_SOURCE_5))
272 + return -EINVAL;
273 +
274 + spin_lock_irqsave(&svpriv->svlock, flags);
275 + svpriv->intsrc[cause].handler = handler;
276 + if (cause_description != NULL)
277 + svpriv->intsrc[cause].intname = cause_description;
278 + if (ext != NULL)
279 + svpriv->intsrc[cause].ext = ext;
280 + spin_unlock_irqrestore(&svpriv->svlock, flags);
281 +
282 + return 0;
283 +}
284 +EXPORT_SYMBOL(snvs_secvio_install_handler);
285 +
286 +/*
287 + * Remove an application-defined handler for a specified cause (and, by
288 + * implication, restore the "default".
289 + * Arguments:
290 + * - dev points to SNVS-owning device
291 + * - cause interrupt source cause
292 + */
293 +int snvs_secvio_remove_handler(struct device *dev, enum secvio_cause cause)
294 +{
295 + unsigned long flags;
296 + struct snvs_secvio_drv_private *svpriv;
297 +
298 + svpriv = dev_get_drvdata(dev);
299 +
300 + if (cause > SECVIO_CAUSE_SOURCE_5)
301 + return -EINVAL;
302 +
303 + spin_lock_irqsave(&svpriv->svlock, flags);
304 + svpriv->intsrc[cause].intname = violation_src_name[cause];
305 + svpriv->intsrc[cause].handler = snvs_secvio_default;
306 + svpriv->intsrc[cause].ext = NULL;
307 + spin_unlock_irqrestore(&svpriv->svlock, flags);
308 + return 0;
309 +}
310 +EXPORT_SYMBOL(snvs_secvio_remove_handler);
311 +
312 +static int snvs_secvio_remove(struct platform_device *pdev)
313 +{
314 + struct device *svdev;
315 + struct snvs_secvio_drv_private *svpriv;
316 + int i;
317 +
318 + svdev = &pdev->dev;
319 + svpriv = dev_get_drvdata(svdev);
320 +
321 + clk_enable(svpriv->clk);
322 + /* Set all sources to nonfatal */
323 + wr_reg32(&svpriv->svregs->hp.secvio_intcfg, 0);
324 +
325 + /* Remove tasklets and release interrupt */
326 + for_each_possible_cpu(i)
327 + tasklet_kill(&svpriv->irqtask[i]);
328 +
329 + clk_disable_unprepare(svpriv->clk);
330 + free_irq(svpriv->irq, svdev);
331 + iounmap(svpriv->svregs);
332 + kfree(svpriv);
333 +
334 + return 0;
335 +}
336 +
337 +static int snvs_secvio_probe(struct platform_device *pdev)
338 +{
339 + struct device *svdev;
340 + struct snvs_secvio_drv_private *svpriv;
341 + struct device_node *np, *npirq;
342 + struct snvs_full __iomem *snvsregs;
343 + int i, error;
344 + u32 hpstate;
345 + const void *jtd, *wtd, *itd, *etd;
346 + u32 td_en;
347 +
348 + svpriv = kzalloc(sizeof(struct snvs_secvio_drv_private), GFP_KERNEL);
349 + if (!svpriv)
350 + return -ENOMEM;
351 +
352 + svdev = &pdev->dev;
353 + dev_set_drvdata(svdev, svpriv);
354 + svpriv->pdev = pdev;
355 + np = pdev->dev.of_node;
356 +
357 + npirq = of_find_compatible_node(NULL, NULL, "fsl,imx6q-caam-secvio");
358 + if (!npirq) {
359 + dev_err(svdev, "can't find secvio node\n");
360 + kfree(svpriv);
361 + return -EINVAL;
362 + }
363 + svpriv->irq = irq_of_parse_and_map(npirq, 0);
364 + if (svpriv->irq <= 0) {
365 + dev_err(svdev, "can't identify secvio interrupt\n");
366 + kfree(svpriv);
367 + return -EINVAL;
368 + }
369 +
370 + jtd = of_get_property(npirq, "jtag-tamper", NULL);
371 + wtd = of_get_property(npirq, "watchdog-tamper", NULL);
372 + itd = of_get_property(npirq, "internal-boot-tamper", NULL);
373 + etd = of_get_property(npirq, "external-pin-tamper", NULL);
374 + if (!jtd | !wtd | !itd | !etd ) {
375 + dev_err(svdev, "can't identify all tamper alarm configuration\n");
376 + kfree(svpriv);
377 + return -EINVAL;
378 + }
379 +
380 + /*
381 + * Configure all sources according to device tree property.
382 + * If the property is enabled then the source is ser as
383 + * fatal violations except LP section,
384 + * source #5 (typically used as an external tamper detect), and
385 + * source #3 (typically unused). Whenever the transition to
386 + * secure mode has occurred, these will now be "fatal" violations
387 + */
388 + td_en = HP_SECVIO_INTEN_SRC0;
389 + if (!strcmp(jtd, "enabled"))
390 + td_en |= HP_SECVIO_INTEN_SRC1;
391 + if (!strcmp(wtd, "enabled"))
392 + td_en |= HP_SECVIO_INTEN_SRC2;
393 + if (!strcmp(itd, "enabled"))
394 + td_en |= HP_SECVIO_INTEN_SRC4;
395 + if (!strcmp(etd, "enabled"))
396 + td_en |= HP_SECVIO_INTEN_SRC5;
397 +
398 + snvsregs = of_iomap(np, 0);
399 + if (!snvsregs) {
400 + dev_err(svdev, "register mapping failed\n");
401 + return -ENOMEM;
402 + }
403 + svpriv->svregs = (struct snvs_full __force *)snvsregs;
404 +
405 + svpriv->clk = devm_clk_get(&pdev->dev, NULL);
406 + if (IS_ERR(svpriv->clk)) {
407 + dev_err(&pdev->dev, "can't get snvs clock\n");
408 + svpriv->clk = NULL;
409 + }
410 +
411 + /* Write the Secvio Enable Config the SVCR */
412 + wr_reg32(&svpriv->svregs->hp.secvio_ctl, td_en);
413 + wr_reg32(&svpriv->svregs->hp.secvio_intcfg, td_en);
414 +
415 + /* Device data set up. Now init interrupt source descriptions */
416 + for (i = 0; i < MAX_SECVIO_SOURCES; i++) {
417 + svpriv->intsrc[i].intname = violation_src_name[i];
418 + svpriv->intsrc[i].handler = snvs_secvio_default;
419 + }
420 + /* Connect main handler */
421 + for_each_possible_cpu(i)
422 + tasklet_init(&svpriv->irqtask[i], snvs_secvio_dispatch,
423 + (unsigned long)svdev);
424 +
425 + error = request_irq(svpriv->irq, snvs_secvio_interrupt,
426 + IRQF_SHARED, DRIVER_NAME, svdev);
427 + if (error) {
428 + dev_err(svdev, "can't connect secvio interrupt\n");
429 + irq_dispose_mapping(svpriv->irq);
430 + svpriv->irq = 0;
431 + iounmap(svpriv->svregs);
432 + kfree(svpriv);
433 + return -EINVAL;
434 + }
435 +
436 + clk_prepare_enable(svpriv->clk);
437 +
438 + hpstate = (rd_reg32(&svpriv->svregs->hp.status) &
439 + HP_STATUS_SSM_ST_MASK) >> HP_STATUS_SSM_ST_SHIFT;
440 + dev_info(svdev, "violation handlers armed - %s state\n",
441 + snvs_ssm_state_name[hpstate]);
442 +
443 + clk_disable(svpriv->clk);
444 +
445 + return 0;
446 +}
447 +
448 +static struct of_device_id snvs_secvio_match[] = {
449 + {
450 + .compatible = "fsl,imx6q-caam-snvs",
451 + },
452 + {},
453 +};
454 +MODULE_DEVICE_TABLE(of, snvs_secvio_match);
455 +
456 +static struct platform_driver snvs_secvio_driver = {
457 + .driver = {
458 + .name = DRIVER_NAME,
459 + .owner = THIS_MODULE,
460 + .of_match_table = snvs_secvio_match,
461 + },
462 + .probe = snvs_secvio_probe,
463 + .remove = snvs_secvio_remove,
464 +};
465 +
466 +module_platform_driver(snvs_secvio_driver);
467 +
468 +MODULE_LICENSE("Dual BSD/GPL");
469 +MODULE_DESCRIPTION("FSL SNVS Security Violation Handler");
470 +MODULE_AUTHOR("Freescale Semiconductor - MCU");
471 --- /dev/null
472 +++ b/drivers/crypto/caam/secvio.h
473 @@ -0,0 +1,69 @@
474 +/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
475 +/*
476 + * CAAM Security Violation Handler
477 + *
478 + * Copyright 2012-2015 Freescale Semiconductor, Inc.
479 + * Copyright 2016-2019 NXP
480 + */
481 +
482 +#ifndef SECVIO_H
483 +#define SECVIO_H
484 +
485 +#include "snvsregs.h"
486 +
487 +
488 +/*
489 + * Defines the published interfaces to install/remove application-specified
490 + * handlers for catching violations
491 + */
492 +
493 +#define MAX_SECVIO_SOURCES 6
494 +
495 +/* these are the untranslated causes */
496 +enum secvio_cause {
497 + SECVIO_CAUSE_SOURCE_0,
498 + SECVIO_CAUSE_SOURCE_1,
499 + SECVIO_CAUSE_SOURCE_2,
500 + SECVIO_CAUSE_SOURCE_3,
501 + SECVIO_CAUSE_SOURCE_4,
502 + SECVIO_CAUSE_SOURCE_5
503 +};
504 +
505 +/* These are common "recommended" cause definitions for most devices */
506 +#define SECVIO_CAUSE_CAAM_VIOLATION SECVIO_CAUSE_SOURCE_0
507 +#define SECVIO_CAUSE_JTAG_ALARM SECVIO_CAUSE_SOURCE_1
508 +#define SECVIO_CAUSE_WATCHDOG SECVIO_CAUSE_SOURCE_2
509 +#define SECVIO_CAUSE_EXTERNAL_BOOT SECVIO_CAUSE_SOURCE_4
510 +#define SECVIO_CAUSE_TAMPER_DETECT SECVIO_CAUSE_SOURCE_5
511 +
512 +int snvs_secvio_install_handler(struct device *dev, enum secvio_cause cause,
513 + void (*handler)(struct device *dev, u32 cause,
514 + void *ext),
515 + u8 *cause_description, void *ext);
516 +int snvs_secvio_remove_handler(struct device *dev, enum secvio_cause cause);
517 +
518 +/*
519 + * Private data definitions for the secvio "driver"
520 + */
521 +
522 +struct secvio_int_src {
523 + const u8 *intname; /* Points to a descriptive name for source */
524 + void *ext; /* Extended data to pass to the handler */
525 + void (*handler)(struct device *dev, u32 cause, void *ext);
526 +};
527 +
528 +struct snvs_secvio_drv_private {
529 + struct platform_device *pdev;
530 + spinlock_t svlock ____cacheline_aligned;
531 + struct tasklet_struct irqtask[NR_CPUS];
532 + struct snvs_full __iomem *svregs; /* both HP and LP domains */
533 + struct clk *clk;
534 + int irq;
535 + u32 irqcause; /* stashed cause of violation interrupt */
536 +
537 + /* Registered handlers for each violation */
538 + struct secvio_int_src intsrc[MAX_SECVIO_SOURCES];
539 +
540 +};
541 +
542 +#endif /* SECVIO_H */
543 --- /dev/null
544 +++ b/drivers/crypto/caam/snvsregs.h
545 @@ -0,0 +1,239 @@
546 +/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
547 +/*
548 + * SNVS hardware register-level view
549 + *
550 + * Copyright 2012-2015 Freescale Semiconductor, Inc.
551 + * Copyright 2016-2019 NXP
552 + */
553 +
554 +#ifndef SNVSREGS_H
555 +#define SNVSREGS_H
556 +
557 +#include <linux/types.h>
558 +#include <linux/io.h>
559 +
560 +/*
561 + * SNVS High Power Domain
562 + * Includes security violations, HA counter, RTC, alarm
563 + */
564 +struct snvs_hp {
565 + u32 lock; /* HPLR - HP Lock */
566 + u32 cmd; /* HPCOMR - HP Command */
567 + u32 ctl; /* HPCR - HP Control */
568 + u32 secvio_intcfg; /* HPSICR - Security Violation Int Config */
569 + u32 secvio_ctl; /* HPSVCR - Security Violation Control */
570 + u32 status; /* HPSR - HP Status */
571 + u32 secvio_status; /* HPSVSR - Security Violation Status */
572 + u32 ha_counteriv; /* High Assurance Counter IV */
573 + u32 ha_counter; /* High Assurance Counter */
574 + u32 rtc_msb; /* Real Time Clock/Counter MSB */
575 + u32 rtc_lsb; /* Real Time Counter LSB */
576 + u32 time_alarm_msb; /* Time Alarm MSB */
577 + u32 time_alarm_lsb; /* Time Alarm LSB */
578 +};
579 +
580 +#define HP_LOCK_HAC_LCK 0x00040000
581 +#define HP_LOCK_HPSICR_LCK 0x00020000
582 +#define HP_LOCK_HPSVCR_LCK 0x00010000
583 +#define HP_LOCK_MKEYSEL_LCK 0x00000200
584 +#define HP_LOCK_TAMPCFG_LCK 0x00000100
585 +#define HP_LOCK_TAMPFLT_LCK 0x00000080
586 +#define HP_LOCK_SECVIO_LCK 0x00000040
587 +#define HP_LOCK_GENP_LCK 0x00000020
588 +#define HP_LOCK_MONOCTR_LCK 0x00000010
589 +#define HP_LOCK_CALIB_LCK 0x00000008
590 +#define HP_LOCK_SRTC_LCK 0x00000004
591 +#define HP_LOCK_ZMK_RD_LCK 0x00000002
592 +#define HP_LOCK_ZMK_WT_LCK 0x00000001
593 +
594 +#define HP_CMD_NONPRIV_AXS 0x80000000
595 +#define HP_CMD_HAC_STOP 0x00080000
596 +#define HP_CMD_HAC_CLEAR 0x00040000
597 +#define HP_CMD_HAC_LOAD 0x00020000
598 +#define HP_CMD_HAC_CFG_EN 0x00010000
599 +#define HP_CMD_SNVS_MSTR_KEY 0x00002000
600 +#define HP_CMD_PROG_ZMK 0x00001000
601 +#define HP_CMD_SW_LPSV 0x00000400
602 +#define HP_CMD_SW_FSV 0x00000200
603 +#define HP_CMD_SW_SV 0x00000100
604 +#define HP_CMD_LP_SWR_DIS 0x00000020
605 +#define HP_CMD_LP_SWR 0x00000010
606 +#define HP_CMD_SSM_SFNS_DIS 0x00000004
607 +#define HP_CMD_SSM_ST_DIS 0x00000002
608 +#define HP_CMD_SMM_ST 0x00000001
609 +
610 +#define HP_CTL_TIME_SYNC 0x00010000
611 +#define HP_CTL_CAL_VAL_SHIFT 10
612 +#define HP_CTL_CAL_VAL_MASK (0x1f << HP_CTL_CALIB_SHIFT)
613 +#define HP_CTL_CALIB_EN 0x00000100
614 +#define HP_CTL_PI_FREQ_SHIFT 4
615 +#define HP_CTL_PI_FREQ_MASK (0xf << HP_CTL_PI_FREQ_SHIFT)
616 +#define HP_CTL_PI_EN 0x00000008
617 +#define HP_CTL_TIMEALARM_EN 0x00000002
618 +#define HP_CTL_RTC_EN 0x00000001
619 +
620 +#define HP_SECVIO_INTEN_EN 0x10000000
621 +#define HP_SECVIO_INTEN_SRC5 0x00000020
622 +#define HP_SECVIO_INTEN_SRC4 0x00000010
623 +#define HP_SECVIO_INTEN_SRC3 0x00000008
624 +#define HP_SECVIO_INTEN_SRC2 0x00000004
625 +#define HP_SECVIO_INTEN_SRC1 0x00000002
626 +#define HP_SECVIO_INTEN_SRC0 0x00000001
627 +#define HP_SECVIO_INTEN_ALL 0x8000003f
628 +
629 +#define HP_SECVIO_ICTL_CFG_SHIFT 30
630 +#define HP_SECVIO_ICTL_CFG_MASK (0x3 << HP_SECVIO_ICTL_CFG_SHIFT)
631 +#define HP_SECVIO_ICTL_CFG5_SHIFT 5
632 +#define HP_SECVIO_ICTL_CFG5_MASK (0x3 << HP_SECVIO_ICTL_CFG5_SHIFT)
633 +#define HP_SECVIO_ICTL_CFG_DISABLE 0
634 +#define HP_SECVIO_ICTL_CFG_NONFATAL 1
635 +#define HP_SECVIO_ICTL_CFG_FATAL 2
636 +#define HP_SECVIO_ICTL_CFG4_FATAL 0x00000010
637 +#define HP_SECVIO_ICTL_CFG3_FATAL 0x00000008
638 +#define HP_SECVIO_ICTL_CFG2_FATAL 0x00000004
639 +#define HP_SECVIO_ICTL_CFG1_FATAL 0x00000002
640 +#define HP_SECVIO_ICTL_CFG0_FATAL 0x00000001
641 +
642 +#define HP_STATUS_ZMK_ZERO 0x80000000
643 +#define HP_STATUS_OTPMK_ZERO 0x08000000
644 +#define HP_STATUS_OTPMK_SYN_SHIFT 16
645 +#define HP_STATUS_OTPMK_SYN_MASK (0x1ff << HP_STATUS_OTPMK_SYN_SHIFT)
646 +#define HP_STATUS_SSM_ST_SHIFT 8
647 +#define HP_STATUS_SSM_ST_MASK (0xf << HP_STATUS_SSM_ST_SHIFT)
648 +#define HP_STATUS_SSM_ST_INIT 0
649 +#define HP_STATUS_SSM_ST_HARDFAIL 1
650 +#define HP_STATUS_SSM_ST_SOFTFAIL 3
651 +#define HP_STATUS_SSM_ST_INITINT 8
652 +#define HP_STATUS_SSM_ST_CHECK 9
653 +#define HP_STATUS_SSM_ST_NONSECURE 11
654 +#define HP_STATUS_SSM_ST_TRUSTED 13
655 +#define HP_STATUS_SSM_ST_SECURE 15
656 +
657 +#define HP_SECVIOST_ZMK_ECC_FAIL 0x08000000 /* write to clear */
658 +#define HP_SECVIOST_ZMK_SYN_SHIFT 16
659 +#define HP_SECVIOST_ZMK_SYN_MASK (0x1ff << HP_SECVIOST_ZMK_SYN_SHIFT)
660 +#define HP_SECVIOST_SECVIO5 0x00000020
661 +#define HP_SECVIOST_SECVIO4 0x00000010
662 +#define HP_SECVIOST_SECVIO3 0x00000008
663 +#define HP_SECVIOST_SECVIO2 0x00000004
664 +#define HP_SECVIOST_SECVIO1 0x00000002
665 +#define HP_SECVIOST_SECVIO0 0x00000001
666 +#define HP_SECVIOST_SECVIOMASK 0x0000003f
667 +
668 +/*
669 + * SNVS Low Power Domain
670 + * Includes glitch detector, SRTC, alarm, monotonic counter, ZMK
671 + */
672 +struct snvs_lp {
673 + u32 lock;
674 + u32 ctl;
675 + u32 mstr_key_ctl; /* Master Key Control */
676 + u32 secvio_ctl; /* Security Violation Control */
677 + u32 tamper_filt_cfg; /* Tamper Glitch Filters Configuration */
678 + u32 tamper_det_cfg; /* Tamper Detectors Configuration */
679 + u32 status;
680 + u32 srtc_msb; /* Secure Real Time Clock/Counter MSB */
681 + u32 srtc_lsb; /* Secure Real Time Clock/Counter LSB */
682 + u32 time_alarm; /* Time Alarm */
683 + u32 smc_msb; /* Secure Monotonic Counter MSB */
684 + u32 smc_lsb; /* Secure Monotonic Counter LSB */
685 + u32 pwr_glitch_det; /* Power Glitch Detector */
686 + u32 gen_purpose;
687 + u32 zmk[8]; /* Zeroizable Master Key */
688 +};
689 +
690 +#define LP_LOCK_MKEYSEL_LCK 0x00000200
691 +#define LP_LOCK_TAMPDET_LCK 0x00000100
692 +#define LP_LOCK_TAMPFLT_LCK 0x00000080
693 +#define LP_LOCK_SECVIO_LCK 0x00000040
694 +#define LP_LOCK_GENP_LCK 0x00000020
695 +#define LP_LOCK_MONOCTR_LCK 0x00000010
696 +#define LP_LOCK_CALIB_LCK 0x00000008
697 +#define LP_LOCK_SRTC_LCK 0x00000004
698 +#define LP_LOCK_ZMK_RD_LCK 0x00000002
699 +#define LP_LOCK_ZMK_WT_LCK 0x00000001
700 +
701 +#define LP_CTL_CAL_VAL_SHIFT 10
702 +#define LP_CTL_CAL_VAL_MASK (0x1f << LP_CTL_CAL_VAL_SHIFT)
703 +#define LP_CTL_CALIB_EN 0x00000100
704 +#define LP_CTL_SRTC_INVAL_EN 0x00000010
705 +#define LP_CTL_WAKE_INT_EN 0x00000008
706 +#define LP_CTL_MONOCTR_EN 0x00000004
707 +#define LP_CTL_TIMEALARM_EN 0x00000002
708 +#define LP_CTL_SRTC_EN 0x00000001
709 +
710 +#define LP_MKEYCTL_ZMKECC_SHIFT 8
711 +#define LP_MKEYCTL_ZMKECC_MASK (0xff << LP_MKEYCTL_ZMKECC_SHIFT)
712 +#define LP_MKEYCTL_ZMKECC_EN 0x00000010
713 +#define LP_MKEYCTL_ZMKECC_VAL 0x00000008
714 +#define LP_MKEYCTL_ZMKECC_PROG 0x00000004
715 +#define LP_MKEYCTL_MKSEL_SHIFT 0
716 +#define LP_MKEYCTL_MKSEL_MASK (3 << LP_MKEYCTL_MKSEL_SHIFT)
717 +#define LP_MKEYCTL_MK_OTP 0
718 +#define LP_MKEYCTL_MK_ZMK 2
719 +#define LP_MKEYCTL_MK_COMB 3
720 +
721 +#define LP_SECVIO_CTL_SRC5 0x20
722 +#define LP_SECVIO_CTL_SRC4 0x10
723 +#define LP_SECVIO_CTL_SRC3 0x08
724 +#define LP_SECVIO_CTL_SRC2 0x04
725 +#define LP_SECVIO_CTL_SRC1 0x02
726 +#define LP_SECVIO_CTL_SRC0 0x01
727 +
728 +#define LP_TAMPFILT_EXT2_EN 0x80000000
729 +#define LP_TAMPFILT_EXT2_SHIFT 24
730 +#define LP_TAMPFILT_EXT2_MASK (0x1f << LP_TAMPFILT_EXT2_SHIFT)
731 +#define LP_TAMPFILT_EXT1_EN 0x00800000
732 +#define LP_TAMPFILT_EXT1_SHIFT 16
733 +#define LP_TAMPFILT_EXT1_MASK (0x1f << LP_TAMPFILT_EXT1_SHIFT)
734 +#define LP_TAMPFILT_WM_EN 0x00000080
735 +#define LP_TAMPFILT_WM_SHIFT 0
736 +#define LP_TAMPFILT_WM_MASK (0x1f << LP_TAMPFILT_WM_SHIFT)
737 +
738 +#define LP_TAMPDET_OSC_BPS 0x10000000
739 +#define LP_TAMPDET_VRC_SHIFT 24
740 +#define LP_TAMPDET_VRC_MASK (3 << LP_TAMPFILT_VRC_SHIFT)
741 +#define LP_TAMPDET_HTDC_SHIFT 20
742 +#define LP_TAMPDET_HTDC_MASK (3 << LP_TAMPFILT_HTDC_SHIFT)
743 +#define LP_TAMPDET_LTDC_SHIFT 16
744 +#define LP_TAMPDET_LTDC_MASK (3 << LP_TAMPFILT_LTDC_SHIFT)
745 +#define LP_TAMPDET_POR_OBS 0x00008000
746 +#define LP_TAMPDET_PFD_OBS 0x00004000
747 +#define LP_TAMPDET_ET2_EN 0x00000400
748 +#define LP_TAMPDET_ET1_EN 0x00000200
749 +#define LP_TAMPDET_WMT2_EN 0x00000100
750 +#define LP_TAMPDET_WMT1_EN 0x00000080
751 +#define LP_TAMPDET_VT_EN 0x00000040
752 +#define LP_TAMPDET_TT_EN 0x00000020
753 +#define LP_TAMPDET_CT_EN 0x00000010
754 +#define LP_TAMPDET_MCR_EN 0x00000004
755 +#define LP_TAMPDET_SRTCR_EN 0x00000002
756 +
757 +#define LP_STATUS_SECURE
758 +#define LP_STATUS_NONSECURE
759 +#define LP_STATUS_SCANEXIT 0x00100000 /* all write 1 clear here on */
760 +#define LP_STATUS_EXT_SECVIO 0x00010000
761 +#define LP_STATUS_ET2 0x00000400
762 +#define LP_STATUS_ET1 0x00000200
763 +#define LP_STATUS_WMT2 0x00000100
764 +#define LP_STATUS_WMT1 0x00000080
765 +#define LP_STATUS_VTD 0x00000040
766 +#define LP_STATUS_TTD 0x00000020
767 +#define LP_STATUS_CTD 0x00000010
768 +#define LP_STATUS_PGD 0x00000008
769 +#define LP_STATUS_MCR 0x00000004
770 +#define LP_STATUS_SRTCR 0x00000002
771 +#define LP_STATUS_LPTA 0x00000001
772 +
773 +/* Full SNVS register page, including version/options */
774 +struct snvs_full {
775 + struct snvs_hp hp;
776 + struct snvs_lp lp;
777 + u32 rsvd[731]; /* deadspace 0x08c-0xbf7 */
778 +
779 + /* Version / Revision / Option ID space - end of register page */
780 + u32 vid; /* 0xbf8 HP Version ID (VID 1) */
781 + u32 opt_rev; /* 0xbfc HP Options / Revision (VID 2) */
782 +};
783 +
784 +#endif /* SNVSREGS_H */