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