blob: 73f5651161cbebecd5fe31c58bbe9df6f0933648 [file] [log] [blame]
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +02001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright 2019-2020 NXP.
4 */
5
6/*
7 * Configuration of the Tamper pins in different mode:
8 * - default (no tamper pins): _default_
9 * - passive mode expecting VCC on the line: "_passive_vcc_"
10 * - passive mode expecting VCC on the line: "_passive_gnd_"
11 * - active mode: "_active_"
12 */
13
14#include <command.h>
15#include <log.h>
16#include <stddef.h>
17#include <common.h>
18#include <asm/arch/sci/sci.h>
19#include <asm/arch-imx8/imx8-pins.h>
20#include <asm/arch-imx8/snvs_security_sc.h>
21
22/* Access to gd */
23DECLARE_GLOBAL_DATA_PTR;
24
25#define SC_WRITE_CONF 1
26
27#define PGD_HEX_VALUE 0x41736166
28#define SRTC_EN 0x1
29#define DP_EN BIT(5)
30
31struct snvs_security_sc_conf {
32 struct snvs_hp_conf {
33 u32 lock; /* HPLR - HP Lock */
34 u32 __cmd; /* HPCOMR - HP Command */
35 u32 __ctl; /* HPCR - HP Control */
36 u32 secvio_intcfg; /* HPSICR - Security Violation Int
37 * Config
38 */
39 u32 secvio_ctl; /* HPSVCR - Security Violation Control*/
40 u32 status; /* HPSR - HP Status */
41 u32 secvio_status; /* HPSVSR - Security Violation Status */
42 u32 __ha_counteriv; /* High Assurance Counter IV */
43 u32 __ha_counter; /* High Assurance Counter */
44 u32 __rtc_msb; /* Real Time Clock/Counter MSB */
45 u32 __rtc_lsb; /* Real Time Counter LSB */
46 u32 __time_alarm_msb; /* Time Alarm MSB */
47 u32 __time_alarm_lsb; /* Time Alarm LSB */
48 } hp;
49 struct snvs_lp_conf {
50 u32 lock;
51 u32 __ctl;
52 u32 __mstr_key_ctl; /* Master Key Control */
53 u32 secvio_ctl; /* Security Violation Control */
54 u32 tamper_filt_cfg; /* Tamper Glitch Filters Configuration*/
55 u32 tamper_det_cfg; /* Tamper Detectors Configuration */
56 u32 status;
57 u32 __srtc_msb; /* Secure Real Time Clock/Counter MSB */
58 u32 __srtc_lsb; /* Secure Real Time Clock/Counter LSB */
59 u32 __time_alarm; /* Time Alarm */
60 u32 __smc_msb; /* Secure Monotonic Counter MSB */
61 u32 __smc_lsb; /* Secure Monotonic Counter LSB */
62 u32 __pwr_glitch_det; /* Power Glitch Detector */
63 u32 __gen_purpose;
64 u8 __zmk[32]; /* Zeroizable Master Key */
65 u32 __rsvd0;
66 u32 __gen_purposes[4]; /* gp0_30 to gp0_33 */
67 u32 tamper_det_cfg2; /* Tamper Detectors Configuration2 */
68 u32 tamper_det_status; /* Tamper Detectors status */
69 u32 tamper_filt1_cfg; /* Tamper Glitch Filter1 Configuration*/
70 u32 tamper_filt2_cfg; /* Tamper Glitch Filter2 Configuration*/
71 u32 __rsvd1[4];
72 u32 act_tamper1_cfg; /* Active Tamper1 Configuration */
73 u32 act_tamper2_cfg; /* Active Tamper2 Configuration */
74 u32 act_tamper3_cfg; /* Active Tamper3 Configuration */
75 u32 act_tamper4_cfg; /* Active Tamper4 Configuration */
76 u32 act_tamper5_cfg; /* Active Tamper5 Configuration */
77 u32 __rsvd2[3];
78 u32 act_tamper_ctl; /* Active Tamper Control */
79 u32 act_tamper_clk_ctl; /* Active Tamper Clock Control */
80 u32 act_tamper_routing_ctl1;/* Active Tamper Routing Control1 */
81 u32 act_tamper_routing_ctl2;/* Active Tamper Routing Control2 */
82 } lp;
83};
84
85static struct snvs_security_sc_conf snvs_default_config = {
86 .hp = {
87 .lock = 0x1f0703ff,
88 .secvio_ctl = 0x3000007f,
89 },
90 .lp = {
91 .lock = 0x1f0003ff,
92 .secvio_ctl = 0x36,
93 .tamper_filt_cfg = 0,
94 .tamper_det_cfg = 0x76, /* analogic tampers
95 * + rollover tampers
96 */
97 .tamper_det_cfg2 = 0,
98 .tamper_filt1_cfg = 0,
99 .tamper_filt2_cfg = 0,
100 .act_tamper1_cfg = 0,
101 .act_tamper2_cfg = 0,
102 .act_tamper3_cfg = 0,
103 .act_tamper4_cfg = 0,
104 .act_tamper5_cfg = 0,
105 .act_tamper_ctl = 0,
106 .act_tamper_clk_ctl = 0,
107 .act_tamper_routing_ctl1 = 0,
108 .act_tamper_routing_ctl2 = 0,
109 }
110};
111
112static struct snvs_security_sc_conf snvs_passive_vcc_config = {
113 .hp = {
114 .lock = 0x1f0703ff,
115 .secvio_ctl = 0x3000007f,
116 },
117 .lp = {
118 .lock = 0x1f0003ff,
119 .secvio_ctl = 0x36,
120 .tamper_filt_cfg = 0,
121 .tamper_det_cfg = 0x276, /* ET1 will trig on line at GND
122 * + analogic tampers
123 * + rollover tampers
124 */
125 .tamper_det_cfg2 = 0,
126 .tamper_filt1_cfg = 0,
127 .tamper_filt2_cfg = 0,
128 .act_tamper1_cfg = 0,
129 .act_tamper2_cfg = 0,
130 .act_tamper3_cfg = 0,
131 .act_tamper4_cfg = 0,
132 .act_tamper5_cfg = 0,
133 .act_tamper_ctl = 0,
134 .act_tamper_clk_ctl = 0,
135 .act_tamper_routing_ctl1 = 0,
136 .act_tamper_routing_ctl2 = 0,
137 }
138};
139
140static struct snvs_security_sc_conf snvs_passive_gnd_config = {
141 .hp = {
142 .lock = 0x1f0703ff,
143 .secvio_ctl = 0x3000007f,
144 },
145 .lp = {
146 .lock = 0x1f0003ff,
147 .secvio_ctl = 0x36,
148 .tamper_filt_cfg = 0,
149 .tamper_det_cfg = 0xa76, /* ET1 will trig on line at VCC
150 * + analogic tampers
151 * + rollover tampers
152 */
153 .tamper_det_cfg2 = 0,
154 .tamper_filt1_cfg = 0,
155 .tamper_filt2_cfg = 0,
156 .act_tamper1_cfg = 0,
157 .act_tamper2_cfg = 0,
158 .act_tamper3_cfg = 0,
159 .act_tamper4_cfg = 0,
160 .act_tamper5_cfg = 0,
161 .act_tamper_ctl = 0,
162 .act_tamper_clk_ctl = 0,
163 .act_tamper_routing_ctl1 = 0,
164 .act_tamper_routing_ctl2 = 0,
165 }
166};
167
168static struct snvs_security_sc_conf snvs_active_config = {
169 .hp = {
170 .lock = 0x1f0703ff,
171 .secvio_ctl = 0x3000007f,
172 },
173 .lp = {
174 .lock = 0x1f0003ff,
175 .secvio_ctl = 0x36,
176 .tamper_filt_cfg = 0x00800000, /* Enable filtering */
177 .tamper_det_cfg = 0x276, /* ET1 enabled + analogic tampers
178 * + rollover tampers
179 */
180 .tamper_det_cfg2 = 0,
181 .tamper_filt1_cfg = 0,
182 .tamper_filt2_cfg = 0,
183 .act_tamper1_cfg = 0x84001111,
184 .act_tamper2_cfg = 0,
185 .act_tamper3_cfg = 0,
186 .act_tamper4_cfg = 0,
187 .act_tamper5_cfg = 0,
188 .act_tamper_ctl = 0x00010001,
189 .act_tamper_clk_ctl = 0,
190 .act_tamper_routing_ctl1 = 0x1,
191 .act_tamper_routing_ctl2 = 0,
192 }
193};
194
195static struct snvs_security_sc_conf *get_snvs_config(void)
196{
197 return &snvs_default_config;
198}
199
200struct snvs_dgo_conf {
201 u32 tamper_offset_ctl;
202 u32 tamper_pull_ctl;
203 u32 tamper_ana_test_ctl;
204 u32 tamper_sensor_trim_ctl;
205 u32 tamper_misc_ctl;
206 u32 tamper_core_volt_mon_ctl;
207};
208
209static struct snvs_dgo_conf snvs_dgo_default_config = {
210 .tamper_misc_ctl = 0x80000000, /* Lock the DGO */
211};
212
213static struct snvs_dgo_conf snvs_dgo_passive_vcc_config = {
214 .tamper_misc_ctl = 0x80000000, /* Lock the DGO */
215 .tamper_pull_ctl = 0x00000001, /* Pull down ET1 */
216 .tamper_ana_test_ctl = 0x20000000, /* Enable tamper */
217};
218
219static struct snvs_dgo_conf snvs_dgo_passive_gnd_config = {
220 .tamper_misc_ctl = 0x80000000, /* Lock the DGO */
221 .tamper_pull_ctl = 0x00000401, /* Pull up ET1 */
222 .tamper_ana_test_ctl = 0x20000000, /* Enable tamper */
223};
224
225static struct snvs_dgo_conf snvs_dgo_active_config = {
226 .tamper_misc_ctl = 0x80000000, /* Lock the DGO */
227 .tamper_ana_test_ctl = 0x20000000, /* Enable tamper */
228};
229
230static struct snvs_dgo_conf *get_snvs_dgo_config(void)
231{
232 return &snvs_dgo_default_config;
233}
234
235struct tamper_pin_cfg {
236 u32 pad;
237 u32 mux_conf;
238};
239
240static struct tamper_pin_cfg tamper_pin_list_default_config[] = {
241 {SC_P_CSI_D00, 0}, /* Tamp_Out0 */
242 {SC_P_CSI_D01, 0}, /* Tamp_Out1 */
243 {SC_P_CSI_D02, 0}, /* Tamp_Out2 */
244 {SC_P_CSI_D03, 0}, /* Tamp_Out3 */
245 {SC_P_CSI_D04, 0}, /* Tamp_Out4 */
246 {SC_P_CSI_D05, 0}, /* Tamp_In0 */
247 {SC_P_CSI_D06, 0}, /* Tamp_In1 */
248 {SC_P_CSI_D07, 0}, /* Tamp_In2 */
249 {SC_P_CSI_HSYNC, 0}, /* Tamp_In3 */
250 {SC_P_CSI_VSYNC, 0}, /* Tamp_In4 */
251};
252
253static struct tamper_pin_cfg tamper_pin_list_passive_vcc_config[] = {
254 {SC_P_CSI_D05, 0x1c000060}, /* Tamp_In0 */ /* Sel tamper + OD input */
255};
256
257static struct tamper_pin_cfg tamper_pin_list_passive_gnd_config[] = {
258 {SC_P_CSI_D05, 0x1c000060}, /* Tamp_In0 */ /* Sel tamper + OD input */
259};
260
261static struct tamper_pin_cfg tamper_pin_list_active_config[] = {
262 {SC_P_CSI_D00, 0x1a000060}, /* Tamp_Out0 */ /* Sel tamper + OD */
263 {SC_P_CSI_D05, 0x1c000060}, /* Tamp_In0 */ /* Sel tamper + OD input */
264};
265
266#define TAMPER_PIN_LIST_CHOSEN tamper_pin_list_default_config
267
268static struct tamper_pin_cfg *get_tamper_pin_cfg_list(u32 *size)
269{
270 *size = sizeof(TAMPER_PIN_LIST_CHOSEN) /
271 sizeof(TAMPER_PIN_LIST_CHOSEN[0]);
272
273 return TAMPER_PIN_LIST_CHOSEN;
274}
275
276#define SC_CONF_OFFSET_OF(_field) \
277 (offsetof(struct snvs_security_sc_conf, _field))
278
279static u32 ptr_value(u32 *_p)
280{
281 return (_p) ? *_p : 0xdeadbeef;
282}
283
284static int check_write_secvio_config(u32 id, u32 *_p1, u32 *_p2,
285 u32 *_p3, u32 *_p4, u32 *_p5,
286 u32 _cnt)
287{
288 int scierr = 0;
289 u32 d1 = ptr_value(_p1);
290 u32 d2 = ptr_value(_p2);
291 u32 d3 = ptr_value(_p3);
292 u32 d4 = ptr_value(_p4);
293 u32 d5 = ptr_value(_p5);
294
295 scierr = sc_seco_secvio_config(-1, id, SC_WRITE_CONF, &d1, &d2, &d3,
296 &d4, &d4, _cnt);
297 if (scierr != SC_ERR_NONE) {
298 printf("Failed to set secvio configuration\n");
299 debug("Failed to set conf id 0x%x with values ", id);
300 debug("0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x (cnt: %d)\n",
301 d1, d2, d3, d4, d5, _cnt);
302 goto exit;
303 }
304
305 if (_p1)
306 *(u32 *)_p1 = d1;
307 if (_p2)
308 *(u32 *)_p2 = d2;
309 if (_p3)
310 *(u32 *)_p3 = d3;
311 if (_p4)
312 *(u32 *)_p4 = d4;
313 if (_p5)
314 *(u32 *)_p5 = d5;
315
316exit:
317 return scierr;
318}
319
320#define SC_CHECK_WRITE1(id, _p1) \
321 check_write_secvio_config(id, _p1, NULL, NULL, NULL, NULL, 1)
322
323static int apply_snvs_config(struct snvs_security_sc_conf *cnf)
324{
325 int scierr = 0;
326
327 debug("%s\n", __func__);
328
329 debug("Applying config:\n"
330 "\thp.lock = 0x%.8x\n"
331 "\thp.secvio_ctl = 0x%.8x\n"
332 "\tlp.lock = 0x%.8x\n"
333 "\tlp.secvio_ctl = 0x%.8x\n"
334 "\tlp.tamper_filt_cfg = 0x%.8x\n"
335 "\tlp.tamper_det_cfg = 0x%.8x\n"
336 "\tlp.tamper_det_cfg2 = 0x%.8x\n"
337 "\tlp.tamper_filt1_cfg = 0x%.8x\n"
338 "\tlp.tamper_filt2_cfg = 0x%.8x\n"
339 "\tlp.act_tamper1_cfg = 0x%.8x\n"
340 "\tlp.act_tamper2_cfg = 0x%.8x\n"
341 "\tlp.act_tamper3_cfg = 0x%.8x\n"
342 "\tlp.act_tamper4_cfg = 0x%.8x\n"
343 "\tlp.act_tamper5_cfg = 0x%.8x\n"
344 "\tlp.act_tamper_ctl = 0x%.8x\n"
345 "\tlp.act_tamper_clk_ctl = 0x%.8x\n"
346 "\tlp.act_tamper_routing_ctl1 = 0x%.8x\n"
347 "\tlp.act_tamper_routing_ctl2 = 0x%.8x\n",
348 cnf->hp.lock,
349 cnf->hp.secvio_ctl,
350 cnf->lp.lock,
351 cnf->lp.secvio_ctl,
352 cnf->lp.tamper_filt_cfg,
353 cnf->lp.tamper_det_cfg,
354 cnf->lp.tamper_det_cfg2,
355 cnf->lp.tamper_filt1_cfg,
356 cnf->lp.tamper_filt2_cfg,
357 cnf->lp.act_tamper1_cfg,
358 cnf->lp.act_tamper2_cfg,
359 cnf->lp.act_tamper3_cfg,
360 cnf->lp.act_tamper4_cfg,
361 cnf->lp.act_tamper5_cfg,
362 cnf->lp.act_tamper_ctl,
363 cnf->lp.act_tamper_clk_ctl,
364 cnf->lp.act_tamper_routing_ctl1,
365 cnf->lp.act_tamper_routing_ctl2);
366
367 scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.tamper_filt_cfg),
368 &cnf->lp.tamper_filt_cfg,
369 &cnf->lp.tamper_filt1_cfg,
370 &cnf->lp.tamper_filt2_cfg, NULL,
371 NULL, 3);
372 if (scierr != SC_ERR_NONE)
373 goto exit;
374
375 /* Configure AT */
376 scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.act_tamper1_cfg),
377 &cnf->lp.act_tamper1_cfg,
378 &cnf->lp.act_tamper2_cfg,
379 &cnf->lp.act_tamper2_cfg,
380 &cnf->lp.act_tamper2_cfg,
381 &cnf->lp.act_tamper2_cfg, 5);
382 if (scierr != SC_ERR_NONE)
383 goto exit;
384
385 /* Configure AT routing */
386 scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.act_tamper_routing_ctl1),
387 &cnf->lp.act_tamper_routing_ctl1,
388 &cnf->lp.act_tamper_routing_ctl2,
389 NULL, NULL, NULL, 2);
390 if (scierr != SC_ERR_NONE)
391 goto exit;
392
393 /* Configure AT frequency */
394 scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.act_tamper_clk_ctl),
395 &cnf->lp.act_tamper_clk_ctl);
396 if (scierr != SC_ERR_NONE)
397 goto exit;
398
399 /* Activate the ATs */
400 scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.act_tamper_ctl),
401 &cnf->lp.act_tamper_ctl);
402 if (scierr != SC_ERR_NONE)
403 goto exit;
404
405 /* Activate the detectors */
406 scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.tamper_det_cfg),
407 &cnf->lp.tamper_det_cfg,
408 &cnf->lp.tamper_det_cfg2, NULL, NULL,
409 NULL, 2);
410 if (scierr != SC_ERR_NONE)
411 goto exit;
412
413 /* Configure LP secvio */
414 scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.secvio_ctl),
415 &cnf->lp.secvio_ctl);
416 if (scierr != SC_ERR_NONE)
417 goto exit;
418
419 /* Configure HP secvio */
420 scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(hp.secvio_ctl),
421 &cnf->hp.secvio_ctl);
422 if (scierr != SC_ERR_NONE)
423 goto exit;
424
425 /* Lock access */
426 scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(hp.lock), &cnf->hp.lock);
427 if (scierr != SC_ERR_NONE)
428 goto exit;
429
430 scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.lock), &cnf->lp.lock);
431 if (scierr != SC_ERR_NONE)
432 goto exit;
433
434exit:
435 return (scierr == SC_ERR_NONE) ? 0 : -EIO;
436}
437
438static int dgo_write(u32 _id, u8 _access, u32 *_pdata)
439{
440 int scierr = sc_seco_secvio_dgo_config(-1, _id, _access, _pdata);
441
442 if (scierr != SC_ERR_NONE) {
443 printf("Failed to set dgo configuration\n");
444 debug("Failed to set conf id 0x%x : 0x%.8x", _id, *_pdata);
445 }
446
447 return scierr;
448}
449
450static int apply_snvs_dgo_config(struct snvs_dgo_conf *cnf)
451{
452 int scierr = 0;
453
454 debug("%s\n", __func__);
455
456 debug("Applying config:\n"
457 "\ttamper_offset_ctl = 0x%.8x\n"
458 "\ttamper_pull_ctl = 0x%.8x\n"
459 "\ttamper_ana_test_ctl = 0x%.8x\n"
460 "\ttamper_sensor_trim_ctl = 0x%.8x\n"
461 "\ttamper_misc_ctl = 0x%.8x\n"
462 "\ttamper_core_volt_mon_ctl = 0x%.8x\n",
463 cnf->tamper_offset_ctl,
464 cnf->tamper_pull_ctl,
465 cnf->tamper_ana_test_ctl,
466 cnf->tamper_sensor_trim_ctl,
467 cnf->tamper_misc_ctl,
468 cnf->tamper_core_volt_mon_ctl);
469
470 dgo_write(0x04, 1, &cnf->tamper_offset_ctl);
471 if (scierr != SC_ERR_NONE)
472 goto exit;
473
474 dgo_write(0x14, 1, &cnf->tamper_pull_ctl);
475 if (scierr != SC_ERR_NONE)
476 goto exit;
477
478 dgo_write(0x24, 1, &cnf->tamper_ana_test_ctl);
479 if (scierr != SC_ERR_NONE)
480 goto exit;
481
482 dgo_write(0x34, 1, &cnf->tamper_sensor_trim_ctl);
483 if (scierr != SC_ERR_NONE)
484 goto exit;
485
486 dgo_write(0x54, 1, &cnf->tamper_core_volt_mon_ctl);
487 if (scierr != SC_ERR_NONE)
488 goto exit;
489
490 /* Last as it could lock the writes */
491 dgo_write(0x44, 1, &cnf->tamper_misc_ctl);
492 if (scierr != SC_ERR_NONE)
493 goto exit;
494
495exit:
496 return (scierr == SC_ERR_NONE) ? 0 : -EIO;
497}
498
499static int pad_write(u32 _pad, u32 _value)
500{
501 int scierr = sc_pad_set(-1, _pad, _value);
502
503 if (scierr != SC_ERR_NONE) {
504 printf("Failed to set pad configuration\n");
505 debug("Failed to set conf pad 0x%x : 0x%.8x", _pad, _value);
506 }
507
508 return scierr;
509}
510
511static int apply_tamper_pin_list_config(struct tamper_pin_cfg *confs, u32 size)
512{
513 int scierr = 0;
514 u32 idx;
515
516 debug("%s\n", __func__);
517
518 for (idx = 0; idx < size; idx++) {
519 debug("\t idx %d: pad %d: 0x%.8x\n", idx, confs[idx].pad,
520 confs[idx].mux_conf);
521 pad_write(confs[idx].pad, 3 << 30 | confs[idx].mux_conf);
522 if (scierr != SC_ERR_NONE)
523 goto exit;
524 }
525
526exit:
527 return (scierr == SC_ERR_NONE) ? 0 : -EIO;
528}
529
530int examples(void)
531{
532 u32 size;
533 struct snvs_security_sc_conf *snvs_conf;
534 struct snvs_dgo_conf *snvs_dgo_conf;
535 struct tamper_pin_cfg *tamper_pin_conf;
536
537 /* Caller */
538 snvs_conf = get_snvs_config();
539 snvs_dgo_conf = get_snvs_dgo_config();
540 tamper_pin_conf = get_tamper_pin_cfg_list(&size);
541
542 /* Default */
543 snvs_conf = &snvs_default_config;
544 snvs_dgo_conf = &snvs_dgo_default_config;
545 tamper_pin_conf = tamper_pin_list_default_config;
546
547 /* Passive tamper expecting VCC on the line */
548 snvs_conf = &snvs_passive_vcc_config;
549 snvs_dgo_conf = &snvs_dgo_passive_vcc_config;
550 tamper_pin_conf = tamper_pin_list_passive_vcc_config;
551
552 /* Passive tamper expecting GND on the line */
553 snvs_conf = &snvs_passive_gnd_config;
554 snvs_dgo_conf = &snvs_dgo_passive_gnd_config;
555 tamper_pin_conf = tamper_pin_list_passive_gnd_config;
556
557 /* Active tamper */
558 snvs_conf = &snvs_active_config;
559 snvs_dgo_conf = &snvs_dgo_active_config;
560 tamper_pin_conf = tamper_pin_list_active_config;
561
562 return !snvs_conf + !snvs_dgo_conf + !tamper_pin_conf;
563}
564
565#ifdef CONFIG_IMX_SNVS_SEC_SC_AUTO
566int snvs_security_sc_init(void)
567{
568 int err = 0;
569
570 struct snvs_security_sc_conf *snvs_conf;
571 struct snvs_dgo_conf *snvs_dgo_conf;
572 struct tamper_pin_cfg *tamper_pin_conf;
573 u32 size;
574
575 debug("%s\n", __func__);
576
577 snvs_conf = get_snvs_config();
578 snvs_dgo_conf = get_snvs_dgo_config();
579
580 tamper_pin_conf = get_tamper_pin_cfg_list(&size);
581
582 err = apply_tamper_pin_list_config(tamper_pin_conf, size);
583 if (err) {
584 debug("Failed to set pins\n");
585 goto exit;
586 }
587
588 err = apply_snvs_dgo_config(snvs_dgo_conf);
589 if (err) {
590 debug("Failed to set dgo\n");
591 goto exit;
592 }
593
594 err = apply_snvs_config(snvs_conf);
595 if (err) {
596 debug("Failed to set snvs\n");
597 goto exit;
598 }
599
600exit:
601 return err;
602}
603#endif /* CONFIG_IMX_SNVS_SEC_SC_AUTO */
604
605static char snvs_cfg_help_text[] =
606 "snvs_cfg\n"
607 "\thp.lock\n"
608 "\thp.secvio_ctl\n"
609 "\tlp.lock\n"
610 "\tlp.secvio_ctl\n"
611 "\tlp.tamper_filt_cfg\n"
612 "\tlp.tamper_det_cfg\n"
613 "\tlp.tamper_det_cfg2\n"
614 "\tlp.tamper_filt1_cfg\n"
615 "\tlp.tamper_filt2_cfg\n"
616 "\tlp.act_tamper1_cfg\n"
617 "\tlp.act_tamper2_cfg\n"
618 "\tlp.act_tamper3_cfg\n"
619 "\tlp.act_tamper4_cfg\n"
620 "\tlp.act_tamper5_cfg\n"
621 "\tlp.act_tamper_ctl\n"
622 "\tlp.act_tamper_clk_ctl\n"
623 "\tlp.act_tamper_routing_ctl1\n"
624 "\tlp.act_tamper_routing_ctl2\n"
625 "\n"
626 "ALL values should be in hexadecimal format";
627
628#define NB_REGISTERS 18
629static int do_snvs_cfg(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
630{
631 int err = 0;
632 u32 idx = 0;
633
634 struct snvs_security_sc_conf conf = {0};
635
636 if (argc != (NB_REGISTERS + 1))
637 return CMD_RET_USAGE;
638
639 conf.hp.lock = simple_strtoul(argv[++idx], NULL, 16);
640 conf.hp.secvio_ctl = simple_strtoul(argv[++idx], NULL, 16);
641 conf.lp.lock = simple_strtoul(argv[++idx], NULL, 16);
642 conf.lp.secvio_ctl = simple_strtoul(argv[++idx], NULL, 16);
643 conf.lp.tamper_filt_cfg = simple_strtoul(argv[++idx], NULL, 16);
644 conf.lp.tamper_det_cfg = simple_strtoul(argv[++idx], NULL, 16);
645 conf.lp.tamper_det_cfg2 = simple_strtoul(argv[++idx], NULL, 16);
646 conf.lp.tamper_filt1_cfg = simple_strtoul(argv[++idx], NULL, 16);
647 conf.lp.tamper_filt2_cfg = simple_strtoul(argv[++idx], NULL, 16);
648 conf.lp.act_tamper1_cfg = simple_strtoul(argv[++idx], NULL, 16);
649 conf.lp.act_tamper2_cfg = simple_strtoul(argv[++idx], NULL, 16);
650 conf.lp.act_tamper3_cfg = simple_strtoul(argv[++idx], NULL, 16);
651 conf.lp.act_tamper4_cfg = simple_strtoul(argv[++idx], NULL, 16);
652 conf.lp.act_tamper5_cfg = simple_strtoul(argv[++idx], NULL, 16);
653 conf.lp.act_tamper_ctl = simple_strtoul(argv[++idx], NULL, 16);
654 conf.lp.act_tamper_clk_ctl = simple_strtoul(argv[++idx], NULL, 16);
655 conf.lp.act_tamper_routing_ctl1 = simple_strtoul(argv[++idx], NULL, 16);
656 conf.lp.act_tamper_routing_ctl2 = simple_strtoul(argv[++idx], NULL, 16);
657
658 err = apply_snvs_config(&conf);
659
660 return err;
661}
662
663U_BOOT_CMD(snvs_cfg,
664 NB_REGISTERS + 1, 1, do_snvs_cfg,
665 "Security violation configuration",
666 snvs_cfg_help_text
667);
668
669static char snvs_dgo_cfg_help_text[] =
670 "snvs_dgo_cfg\n"
671 "\ttamper_offset_ctl\n"
672 "\ttamper_pull_ctl\n"
673 "\ttamper_ana_test_ctl\n"
674 "\ttamper_sensor_trim_ctl\n"
675 "\ttamper_misc_ctl\n"
676 "\ttamper_core_volt_mon_ctl\n"
677 "\n"
678 "ALL values should be in hexadecimal format";
679
680static int do_snvs_dgo_cfg(cmd_tbl_t *cmdtp, int flag, int argc,
681 char *const argv[])
682{
683 int err = 0;
684 u32 idx = 0;
685
686 struct snvs_dgo_conf conf = {0};
687
688 if (argc != (6 + 1))
689 return CMD_RET_USAGE;
690
691 conf.tamper_offset_ctl = simple_strtoul(argv[++idx], NULL, 16);
692 conf.tamper_pull_ctl = simple_strtoul(argv[++idx], NULL, 16);
693 conf.tamper_ana_test_ctl = simple_strtoul(argv[++idx], NULL, 16);
694 conf.tamper_sensor_trim_ctl = simple_strtoul(argv[++idx], NULL, 16);
695 conf.tamper_misc_ctl = simple_strtoul(argv[++idx], NULL, 16);
696 conf.tamper_core_volt_mon_ctl = simple_strtoul(argv[++idx], NULL, 16);
697
698 err = apply_snvs_dgo_config(&conf);
699
700 return err;
701}
702
703U_BOOT_CMD(snvs_dgo_cfg,
704 7, 1, do_snvs_dgo_cfg,
705 "SNVS DGO configuration",
706 snvs_dgo_cfg_help_text
707);
708
709static char tamper_pin_cfg_help_text[] =
710 "snvs_dgo_cfg\n"
711 "\tpad\n"
712 "\tvalue\n"
713 "\n"
714 "ALL values should be in hexadecimal format";
715
716static int do_tamper_pin_cfg(cmd_tbl_t *cmdtp, int flag, int argc,
717 char *const argv[])
718{
719 int err = 0;
720 u32 idx = 0;
721
722 struct tamper_pin_cfg conf = {0};
723
724 if (argc != (2 + 1))
725 return CMD_RET_USAGE;
726
727 conf.pad = simple_strtoul(argv[++idx], NULL, 10);
728 conf.mux_conf = simple_strtoul(argv[++idx], NULL, 16);
729
730 err = apply_tamper_pin_list_config(&conf, 1);
731
732 return err;
733}
734
735U_BOOT_CMD(tamper_pin_cfg,
736 3, 1, do_tamper_pin_cfg,
737 "tamper pin configuration",
738 tamper_pin_cfg_help_text
739);
740
741static char snvs_clear_status_help_text[] =
742 "snvs_clear_status\n"
743 "\tHPSR\n"
744 "\tHPSVSR\n"
745 "\tLPSR\n"
746 "\tLPTDSR\n"
747 "\n"
748 "Write the status registers with the value provided,"
749 " clearing the status";
750
751static int do_snvs_clear_status(cmd_tbl_t *cmdtp, int flag, int argc,
752 char *const argv[])
753{
754 int scierr = 0;
755 u32 idx = 0;
756
757 struct snvs_security_sc_conf conf = {0};
758
759 if (argc != (2 + 1))
760 return CMD_RET_USAGE;
761
762 conf.lp.status = simple_strtoul(argv[++idx], NULL, 16);
763 conf.lp.tamper_det_status = simple_strtoul(argv[++idx], NULL, 16);
764
765 scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.status),
766 &conf.lp.status, NULL, NULL, NULL,
767 NULL, 1);
768 if (scierr != SC_ERR_NONE)
769 goto exit;
770
771 scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.tamper_det_status),
772 &conf.lp.tamper_det_status, NULL,
773 NULL, NULL, NULL, 1);
774 if (scierr != SC_ERR_NONE)
775 goto exit;
776
777exit:
778 return (scierr == SC_ERR_NONE) ? 0 : 1;
779}
780
781U_BOOT_CMD(snvs_clear_status,
782 3, 1, do_snvs_clear_status,
783 "snvs clear status",
784 snvs_clear_status_help_text
785);
786
787static char snvs_sec_status_help_text[] =
788 "snvs_sec_status\n"
789 "Display information about the security related to tamper and secvio";
790
791static int do_snvs_sec_status(cmd_tbl_t *cmdtp, int flag, int argc,
792 char *const argv[])
793{
794 int scierr;
795 u32 idx;
796
797 u32 data[5];
798
799 u32 pads[] = {
800 SC_P_CSI_D00,
801 SC_P_CSI_D01,
802 SC_P_CSI_D02,
803 SC_P_CSI_D03,
804 SC_P_CSI_D04,
805 SC_P_CSI_D05,
806 SC_P_CSI_D06,
807 SC_P_CSI_D07,
808 SC_P_CSI_HSYNC,
809 SC_P_CSI_VSYNC,
810 };
811
812 u32 fuses[] = {
813 14,
814 30,
815 31,
816 260,
817 261,
818 262,
819 263,
820 768,
821 };
822
823 struct snvs_reg {
824 u32 id;
825 u32 nb;
826 } snvs[] = {
827 /* Locks */
828 {0x0, 1},
829 {0x34, 1},
830 /* Security violation */
831 {0xc, 1},
832 {0x10, 1},
833 {0x18, 1},
834 {0x40, 1},
835 /* Temper detectors */
836 {0x48, 2},
837 {0x4c, 1},
838 {0xa4, 1},
839 /* */
840 {0x44, 3},
841 {0xe0, 1},
842 {0xe4, 1},
843 {0xe8, 2},
844 /* Misc */
845 {0x3c, 1},
846 {0x5c, 2},
847 {0x64, 1},
848 {0xf8, 2},
849 };
850
851 u32 dgo[] = {
852 0x0,
853 0x10,
854 0x20,
855 0x30,
856 0x40,
857 0x50,
858 };
859
860 /* Pins */
861 printf("Pins:\n");
862 for (idx = 0; idx < ARRAY_SIZE(pads); idx++) {
863 u8 pad_id = pads[idx];
864
865 scierr = sc_pad_get(-1, pad_id, &data[0]);
866 if (scierr == 0)
867 printf("\t- Pin %d: %.8x\n", pad_id, data[0]);
868 else
869 printf("Failed to read Pin %d\n", pad_id);
870 }
871
872 /* Fuses */
873 printf("Fuses:\n");
874 for (idx = 0; idx < ARRAY_SIZE(fuses); idx++) {
875 u32 fuse_id = fuses[idx];
876
877 scierr = sc_misc_otp_fuse_read(-1, fuse_id, &data[0]);
878 if (scierr == 0)
879 printf("\t- Fuse %d: %.8x\n", fuse_id, data[0]);
880 else
881 printf("Failed to read Fuse %d\n", fuse_id);
882 }
883
884 /* SNVS */
885 printf("SNVS:\n");
886 for (idx = 0; idx < ARRAY_SIZE(snvs); idx++) {
887 struct snvs_reg *reg = &snvs[idx];
888
889 scierr = sc_seco_secvio_config(-1, reg->id, 0, &data[0],
890 &data[1], &data[2], &data[3],
891 &data[4], reg->nb);
892 if (scierr == 0) {
893 int subidx;
894
895 printf("\t- SNVS %.2x(%d):", reg->id, reg->nb);
896 for (subidx = 0; subidx < reg->nb; subidx++)
897 printf(" %.8x", data[subidx]);
898 printf("\n");
899 } else {
900 printf("Failed to read SNVS %d\n", reg->id);
901 }
902 }
903
904 /* DGO */
905 printf("DGO:\n");
906 for (idx = 0; idx < ARRAY_SIZE(dgo); idx++) {
907 u8 dgo_id = dgo[idx];
908
909 scierr = sc_seco_secvio_dgo_config(-1, dgo_id, 0, &data[0]);
910 if (scierr == 0)
911 printf("\t- DGO %.2x: %.8x\n", dgo_id, data[0]);
912 else
913 printf("Failed to read DGO %d\n", dgo_id);
914 }
915
916 return 0;
917}
918
919U_BOOT_CMD(snvs_sec_status,
920 1, 1, do_snvs_sec_status,
921 "tamper pin configuration",
922 snvs_sec_status_help_text
923);