uboot/arch/arm/mach-imx/imx8/snvs_security_sc.c
<<
>>
Prefs
   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 scierr = 0;
 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        scierr = sc_seco_secvio_config(-1, id, SC_WRITE_CONF, &d1, &d2, &d3,
 297                                       &d4, &d4, _cnt);
 298        if (scierr != SC_ERR_NONE) {
 299                printf("Failed to set secvio configuration\n");
 300                debug("Failed to set conf id 0x%x with values ", id);
 301                debug("0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x (cnt: %d)\n",
 302                      d1, d2, d3, d4, d5, _cnt);
 303                goto exit;
 304        }
 305
 306        if (_p1)
 307                *(u32 *)_p1 = d1;
 308        if (_p2)
 309                *(u32 *)_p2 = d2;
 310        if (_p3)
 311                *(u32 *)_p3 = d3;
 312        if (_p4)
 313                *(u32 *)_p4 = d4;
 314        if (_p5)
 315                *(u32 *)_p5 = d5;
 316
 317exit:
 318        return scierr;
 319}
 320
 321#define SC_CHECK_WRITE1(id, _p1) \
 322        check_write_secvio_config(id, _p1, NULL, NULL, NULL, NULL, 1)
 323
 324static int apply_snvs_config(struct snvs_security_sc_conf *cnf)
 325{
 326        int scierr = 0;
 327
 328        debug("%s\n", __func__);
 329
 330        debug("Applying config:\n"
 331                  "\thp.lock = 0x%.8x\n"
 332                  "\thp.secvio_ctl = 0x%.8x\n"
 333                  "\tlp.lock = 0x%.8x\n"
 334                  "\tlp.secvio_ctl = 0x%.8x\n"
 335                  "\tlp.tamper_filt_cfg = 0x%.8x\n"
 336                  "\tlp.tamper_det_cfg = 0x%.8x\n"
 337                  "\tlp.tamper_det_cfg2 = 0x%.8x\n"
 338                  "\tlp.tamper_filt1_cfg = 0x%.8x\n"
 339                  "\tlp.tamper_filt2_cfg = 0x%.8x\n"
 340                  "\tlp.act_tamper1_cfg = 0x%.8x\n"
 341                  "\tlp.act_tamper2_cfg = 0x%.8x\n"
 342                  "\tlp.act_tamper3_cfg = 0x%.8x\n"
 343                  "\tlp.act_tamper4_cfg = 0x%.8x\n"
 344                  "\tlp.act_tamper5_cfg = 0x%.8x\n"
 345                  "\tlp.act_tamper_ctl = 0x%.8x\n"
 346                  "\tlp.act_tamper_clk_ctl = 0x%.8x\n"
 347                  "\tlp.act_tamper_routing_ctl1 = 0x%.8x\n"
 348                  "\tlp.act_tamper_routing_ctl2 = 0x%.8x\n",
 349                        cnf->hp.lock,
 350                        cnf->hp.secvio_ctl,
 351                        cnf->lp.lock,
 352                        cnf->lp.secvio_ctl,
 353                        cnf->lp.tamper_filt_cfg,
 354                        cnf->lp.tamper_det_cfg,
 355                        cnf->lp.tamper_det_cfg2,
 356                        cnf->lp.tamper_filt1_cfg,
 357                        cnf->lp.tamper_filt2_cfg,
 358                        cnf->lp.act_tamper1_cfg,
 359                        cnf->lp.act_tamper2_cfg,
 360                        cnf->lp.act_tamper3_cfg,
 361                        cnf->lp.act_tamper4_cfg,
 362                        cnf->lp.act_tamper5_cfg,
 363                        cnf->lp.act_tamper_ctl,
 364                        cnf->lp.act_tamper_clk_ctl,
 365                        cnf->lp.act_tamper_routing_ctl1,
 366                        cnf->lp.act_tamper_routing_ctl2);
 367
 368        scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.tamper_filt_cfg),
 369                                           &cnf->lp.tamper_filt_cfg,
 370                                           &cnf->lp.tamper_filt1_cfg,
 371                                           &cnf->lp.tamper_filt2_cfg, NULL,
 372                                           NULL, 3);
 373        if (scierr != SC_ERR_NONE)
 374                goto exit;
 375
 376        /* Configure AT */
 377        scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.act_tamper1_cfg),
 378                                           &cnf->lp.act_tamper1_cfg,
 379                                           &cnf->lp.act_tamper2_cfg,
 380                                           &cnf->lp.act_tamper2_cfg,
 381                                           &cnf->lp.act_tamper2_cfg,
 382                                           &cnf->lp.act_tamper2_cfg, 5);
 383        if (scierr != SC_ERR_NONE)
 384                goto exit;
 385
 386        /* Configure AT routing */
 387        scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.act_tamper_routing_ctl1),
 388                                           &cnf->lp.act_tamper_routing_ctl1,
 389                                           &cnf->lp.act_tamper_routing_ctl2,
 390                                           NULL, NULL, NULL, 2);
 391        if (scierr != SC_ERR_NONE)
 392                goto exit;
 393
 394        /* Configure AT frequency */
 395        scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.act_tamper_clk_ctl),
 396                                 &cnf->lp.act_tamper_clk_ctl);
 397        if (scierr != SC_ERR_NONE)
 398                goto exit;
 399
 400        /* Activate the ATs */
 401        scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.act_tamper_ctl),
 402                                 &cnf->lp.act_tamper_ctl);
 403        if (scierr != SC_ERR_NONE)
 404                goto exit;
 405
 406        /* Activate the detectors */
 407        scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.tamper_det_cfg),
 408                                           &cnf->lp.tamper_det_cfg,
 409                                           &cnf->lp.tamper_det_cfg2, NULL, NULL,
 410                                           NULL, 2);
 411        if (scierr != SC_ERR_NONE)
 412                goto exit;
 413
 414        /* Configure LP secvio */
 415        scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.secvio_ctl),
 416                                 &cnf->lp.secvio_ctl);
 417        if (scierr != SC_ERR_NONE)
 418                goto exit;
 419
 420        /* Configure HP secvio */
 421        scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(hp.secvio_ctl),
 422                                 &cnf->hp.secvio_ctl);
 423        if (scierr != SC_ERR_NONE)
 424                goto exit;
 425
 426        /* Lock access */
 427        scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(hp.lock), &cnf->hp.lock);
 428        if (scierr != SC_ERR_NONE)
 429                goto exit;
 430
 431        scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.lock), &cnf->lp.lock);
 432        if (scierr != SC_ERR_NONE)
 433                goto exit;
 434
 435exit:
 436        return (scierr == SC_ERR_NONE) ? 0 : -EIO;
 437}
 438
 439static int dgo_write(u32 _id, u8 _access, u32 *_pdata)
 440{
 441        int scierr = sc_seco_secvio_dgo_config(-1, _id, _access, _pdata);
 442
 443        if (scierr != SC_ERR_NONE) {
 444                printf("Failed to set dgo configuration\n");
 445                debug("Failed to set conf id 0x%x : 0x%.8x", _id, *_pdata);
 446        }
 447
 448        return scierr;
 449}
 450
 451static int apply_snvs_dgo_config(struct snvs_dgo_conf *cnf)
 452{
 453        int scierr = 0;
 454
 455        debug("%s\n", __func__);
 456
 457        debug("Applying config:\n"
 458                "\ttamper_offset_ctl = 0x%.8x\n"
 459                "\ttamper_pull_ctl = 0x%.8x\n"
 460                "\ttamper_ana_test_ctl = 0x%.8x\n"
 461                "\ttamper_sensor_trim_ctl = 0x%.8x\n"
 462                "\ttamper_misc_ctl = 0x%.8x\n"
 463                "\ttamper_core_volt_mon_ctl = 0x%.8x\n",
 464                        cnf->tamper_offset_ctl,
 465                        cnf->tamper_pull_ctl,
 466                        cnf->tamper_ana_test_ctl,
 467                        cnf->tamper_sensor_trim_ctl,
 468                        cnf->tamper_misc_ctl,
 469                        cnf->tamper_core_volt_mon_ctl);
 470
 471        dgo_write(0x04, 1, &cnf->tamper_offset_ctl);
 472        if (scierr != SC_ERR_NONE)
 473                goto exit;
 474
 475        dgo_write(0x14, 1, &cnf->tamper_pull_ctl);
 476        if (scierr != SC_ERR_NONE)
 477                goto exit;
 478
 479        dgo_write(0x24, 1, &cnf->tamper_ana_test_ctl);
 480        if (scierr != SC_ERR_NONE)
 481                goto exit;
 482
 483        dgo_write(0x34, 1, &cnf->tamper_sensor_trim_ctl);
 484        if (scierr != SC_ERR_NONE)
 485                goto exit;
 486
 487        dgo_write(0x54, 1, &cnf->tamper_core_volt_mon_ctl);
 488        if (scierr != SC_ERR_NONE)
 489                goto exit;
 490
 491        /* Last as it could lock the writes */
 492        dgo_write(0x44, 1, &cnf->tamper_misc_ctl);
 493        if (scierr != SC_ERR_NONE)
 494                goto exit;
 495
 496exit:
 497        return (scierr == SC_ERR_NONE) ? 0 : -EIO;
 498}
 499
 500static int pad_write(u32 _pad, u32 _value)
 501{
 502        int scierr = sc_pad_set(-1, _pad, _value);
 503
 504        if (scierr != SC_ERR_NONE) {
 505                printf("Failed to set pad configuration\n");
 506                debug("Failed to set conf pad 0x%x : 0x%.8x", _pad, _value);
 507        }
 508
 509        return scierr;
 510}
 511
 512static int apply_tamper_pin_list_config(struct tamper_pin_cfg *confs, u32 size)
 513{
 514        int scierr = 0;
 515        u32 idx;
 516
 517        debug("%s\n", __func__);
 518
 519        for (idx = 0; idx < size; idx++) {
 520                debug("\t idx %d: pad %d: 0x%.8x\n", idx, confs[idx].pad,
 521                      confs[idx].mux_conf);
 522                pad_write(confs[idx].pad, 3 << 30 | confs[idx].mux_conf);
 523                if (scierr != SC_ERR_NONE)
 524                        goto exit;
 525        }
 526
 527exit:
 528        return (scierr == SC_ERR_NONE) ? 0 : -EIO;
 529}
 530
 531int examples(void)
 532{
 533        u32 size;
 534        struct snvs_security_sc_conf *snvs_conf;
 535        struct snvs_dgo_conf *snvs_dgo_conf;
 536        struct tamper_pin_cfg *tamper_pin_conf;
 537
 538        /* Caller */
 539        snvs_conf = get_snvs_config();
 540        snvs_dgo_conf = get_snvs_dgo_config();
 541        tamper_pin_conf = get_tamper_pin_cfg_list(&size);
 542
 543        /* Default */
 544        snvs_conf = &snvs_default_config;
 545        snvs_dgo_conf = &snvs_dgo_default_config;
 546        tamper_pin_conf = tamper_pin_list_default_config;
 547
 548        /* Passive tamper expecting VCC on the line */
 549        snvs_conf = &snvs_passive_vcc_config;
 550        snvs_dgo_conf = &snvs_dgo_passive_vcc_config;
 551        tamper_pin_conf = tamper_pin_list_passive_vcc_config;
 552
 553        /* Passive tamper expecting GND on the line */
 554        snvs_conf = &snvs_passive_gnd_config;
 555        snvs_dgo_conf = &snvs_dgo_passive_gnd_config;
 556        tamper_pin_conf = tamper_pin_list_passive_gnd_config;
 557
 558        /* Active tamper */
 559        snvs_conf = &snvs_active_config;
 560        snvs_dgo_conf = &snvs_dgo_active_config;
 561        tamper_pin_conf = tamper_pin_list_active_config;
 562
 563        return !snvs_conf + !snvs_dgo_conf + !tamper_pin_conf;
 564}
 565
 566#ifdef CONFIG_IMX_SNVS_SEC_SC_AUTO
 567int snvs_security_sc_init(void)
 568{
 569        int err = 0;
 570
 571        struct snvs_security_sc_conf *snvs_conf;
 572        struct snvs_dgo_conf *snvs_dgo_conf;
 573        struct tamper_pin_cfg *tamper_pin_conf;
 574        u32 size;
 575
 576        debug("%s\n", __func__);
 577
 578        snvs_conf = get_snvs_config();
 579        snvs_dgo_conf = get_snvs_dgo_config();
 580
 581        tamper_pin_conf = get_tamper_pin_cfg_list(&size);
 582
 583        err = apply_tamper_pin_list_config(tamper_pin_conf, size);
 584        if (err) {
 585                debug("Failed to set pins\n");
 586                goto exit;
 587        }
 588
 589        err = apply_snvs_dgo_config(snvs_dgo_conf);
 590        if (err) {
 591                debug("Failed to set dgo\n");
 592                goto exit;
 593        }
 594
 595        err = apply_snvs_config(snvs_conf);
 596        if (err) {
 597                debug("Failed to set snvs\n");
 598                goto exit;
 599        }
 600
 601exit:
 602        return err;
 603}
 604#endif /* CONFIG_IMX_SNVS_SEC_SC_AUTO */
 605
 606static char snvs_cfg_help_text[] =
 607        "snvs_cfg\n"
 608        "\thp.lock\n"
 609        "\thp.secvio_ctl\n"
 610        "\tlp.lock\n"
 611        "\tlp.secvio_ctl\n"
 612        "\tlp.tamper_filt_cfg\n"
 613        "\tlp.tamper_det_cfg\n"
 614        "\tlp.tamper_det_cfg2\n"
 615        "\tlp.tamper_filt1_cfg\n"
 616        "\tlp.tamper_filt2_cfg\n"
 617        "\tlp.act_tamper1_cfg\n"
 618        "\tlp.act_tamper2_cfg\n"
 619        "\tlp.act_tamper3_cfg\n"
 620        "\tlp.act_tamper4_cfg\n"
 621        "\tlp.act_tamper5_cfg\n"
 622        "\tlp.act_tamper_ctl\n"
 623        "\tlp.act_tamper_clk_ctl\n"
 624        "\tlp.act_tamper_routing_ctl1\n"
 625        "\tlp.act_tamper_routing_ctl2\n"
 626        "\n"
 627        "ALL values should be in hexadecimal format";
 628
 629#define NB_REGISTERS 18
 630static int do_snvs_cfg(struct cmd_tbl *cmdtp, int flag, int argc,
 631                       char *const argv[])
 632{
 633        int err = 0;
 634        u32 idx = 0;
 635
 636        struct snvs_security_sc_conf conf = {0};
 637
 638        if (argc != (NB_REGISTERS + 1))
 639                return CMD_RET_USAGE;
 640
 641        conf.hp.lock = hextoul(argv[++idx], NULL);
 642        conf.hp.secvio_ctl = hextoul(argv[++idx], NULL);
 643        conf.lp.lock = hextoul(argv[++idx], NULL);
 644        conf.lp.secvio_ctl = hextoul(argv[++idx], NULL);
 645        conf.lp.tamper_filt_cfg = hextoul(argv[++idx], NULL);
 646        conf.lp.tamper_det_cfg = hextoul(argv[++idx], NULL);
 647        conf.lp.tamper_det_cfg2 = hextoul(argv[++idx], NULL);
 648        conf.lp.tamper_filt1_cfg = hextoul(argv[++idx], NULL);
 649        conf.lp.tamper_filt2_cfg = hextoul(argv[++idx], NULL);
 650        conf.lp.act_tamper1_cfg = hextoul(argv[++idx], NULL);
 651        conf.lp.act_tamper2_cfg = hextoul(argv[++idx], NULL);
 652        conf.lp.act_tamper3_cfg = hextoul(argv[++idx], NULL);
 653        conf.lp.act_tamper4_cfg = hextoul(argv[++idx], NULL);
 654        conf.lp.act_tamper5_cfg = hextoul(argv[++idx], NULL);
 655        conf.lp.act_tamper_ctl = hextoul(argv[++idx], NULL);
 656        conf.lp.act_tamper_clk_ctl = hextoul(argv[++idx], NULL);
 657        conf.lp.act_tamper_routing_ctl1 = hextoul(argv[++idx], NULL);
 658        conf.lp.act_tamper_routing_ctl2 = hextoul(argv[++idx], NULL);
 659
 660        err = apply_snvs_config(&conf);
 661
 662        return err;
 663}
 664
 665U_BOOT_CMD(snvs_cfg,
 666           NB_REGISTERS + 1, 1, do_snvs_cfg,
 667           "Security violation configuration",
 668           snvs_cfg_help_text
 669);
 670
 671static char snvs_dgo_cfg_help_text[] =
 672        "snvs_dgo_cfg\n"
 673        "\ttamper_offset_ctl\n"
 674        "\ttamper_pull_ctl\n"
 675        "\ttamper_ana_test_ctl\n"
 676        "\ttamper_sensor_trim_ctl\n"
 677        "\ttamper_misc_ctl\n"
 678        "\ttamper_core_volt_mon_ctl\n"
 679        "\n"
 680        "ALL values should be in hexadecimal format";
 681
 682static int do_snvs_dgo_cfg(struct cmd_tbl *cmdtp, int flag, int argc,
 683                           char *const argv[])
 684{
 685        int err = 0;
 686        u32 idx = 0;
 687
 688        struct snvs_dgo_conf conf = {0};
 689
 690        if (argc != (6 + 1))
 691                return CMD_RET_USAGE;
 692
 693        conf.tamper_offset_ctl = hextoul(argv[++idx], NULL);
 694        conf.tamper_pull_ctl = hextoul(argv[++idx], NULL);
 695        conf.tamper_ana_test_ctl = hextoul(argv[++idx], NULL);
 696        conf.tamper_sensor_trim_ctl = hextoul(argv[++idx], NULL);
 697        conf.tamper_misc_ctl = hextoul(argv[++idx], NULL);
 698        conf.tamper_core_volt_mon_ctl = hextoul(argv[++idx], NULL);
 699
 700        err = apply_snvs_dgo_config(&conf);
 701
 702        return err;
 703}
 704
 705U_BOOT_CMD(snvs_dgo_cfg,
 706           7, 1, do_snvs_dgo_cfg,
 707           "SNVS DGO configuration",
 708           snvs_dgo_cfg_help_text
 709);
 710
 711static char tamper_pin_cfg_help_text[] =
 712        "snvs_dgo_cfg\n"
 713        "\tpad\n"
 714        "\tvalue\n"
 715        "\n"
 716        "ALL values should be in hexadecimal format";
 717
 718static int do_tamper_pin_cfg(struct cmd_tbl *cmdtp, int flag, int argc,
 719                             char *const argv[])
 720{
 721        int err = 0;
 722        u32 idx = 0;
 723
 724        struct tamper_pin_cfg conf = {0};
 725
 726        if (argc != (2 + 1))
 727                return CMD_RET_USAGE;
 728
 729        conf.pad = dectoul(argv[++idx], NULL);
 730        conf.mux_conf = hextoul(argv[++idx], NULL);
 731
 732        err = apply_tamper_pin_list_config(&conf, 1);
 733
 734        return err;
 735}
 736
 737U_BOOT_CMD(tamper_pin_cfg,
 738           3, 1, do_tamper_pin_cfg,
 739           "tamper pin configuration",
 740           tamper_pin_cfg_help_text
 741);
 742
 743static char snvs_clear_status_help_text[] =
 744        "snvs_clear_status\n"
 745        "\tHPSR\n"
 746        "\tHPSVSR\n"
 747        "\tLPSR\n"
 748        "\tLPTDSR\n"
 749        "\n"
 750        "Write the status registers with the value provided,"
 751        " clearing the status";
 752
 753static int do_snvs_clear_status(struct cmd_tbl *cmdtp, int flag, int argc,
 754                                char *const argv[])
 755{
 756        int scierr = 0;
 757        u32 idx = 0;
 758
 759        struct snvs_security_sc_conf conf = {0};
 760
 761        if (argc != (2 + 1))
 762                return CMD_RET_USAGE;
 763
 764        conf.lp.status = hextoul(argv[++idx], NULL);
 765        conf.lp.tamper_det_status = hextoul(argv[++idx], NULL);
 766
 767        scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.status),
 768                                           &conf.lp.status, NULL, NULL, NULL,
 769                                           NULL, 1);
 770        if (scierr != SC_ERR_NONE)
 771                goto exit;
 772
 773        scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.tamper_det_status),
 774                                           &conf.lp.tamper_det_status, NULL,
 775                                           NULL, NULL, NULL, 1);
 776        if (scierr != SC_ERR_NONE)
 777                goto exit;
 778
 779exit:
 780        return (scierr == SC_ERR_NONE) ? 0 : 1;
 781}
 782
 783U_BOOT_CMD(snvs_clear_status,
 784           3, 1, do_snvs_clear_status,
 785           "snvs clear status",
 786           snvs_clear_status_help_text
 787);
 788
 789static char snvs_sec_status_help_text[] =
 790        "snvs_sec_status\n"
 791        "Display information about the security related to tamper and secvio";
 792
 793static int do_snvs_sec_status(struct cmd_tbl *cmdtp, int flag, int argc,
 794                              char *const argv[])
 795{
 796        int scierr;
 797        u32 idx;
 798
 799        u32 data[5];
 800
 801        u32 pads[] = {
 802                SC_P_CSI_D00,
 803                SC_P_CSI_D01,
 804                SC_P_CSI_D02,
 805                SC_P_CSI_D03,
 806                SC_P_CSI_D04,
 807                SC_P_CSI_D05,
 808                SC_P_CSI_D06,
 809                SC_P_CSI_D07,
 810                SC_P_CSI_HSYNC,
 811                SC_P_CSI_VSYNC,
 812        };
 813
 814        u32 fuses[] = {
 815                14,
 816                30,
 817                31,
 818                260,
 819                261,
 820                262,
 821                263,
 822                768,
 823        };
 824
 825        struct snvs_reg {
 826                u32 id;
 827                u32 nb;
 828        } snvs[] = {
 829                /* Locks */
 830                {0x0,  1},
 831                {0x34, 1},
 832                /* Security violation */
 833                {0xc,  1},
 834                {0x10, 1},
 835                {0x18, 1},
 836                {0x40, 1},
 837                /* Temper detectors */
 838                {0x48, 2},
 839                {0x4c, 1},
 840                {0xa4, 1},
 841                /* */
 842                {0x44, 3},
 843                {0xe0, 1},
 844                {0xe4, 1},
 845                {0xe8, 2},
 846                /* Misc */
 847                {0x3c, 1},
 848                {0x5c, 2},
 849                {0x64, 1},
 850                {0xf8, 2},
 851        };
 852
 853        u32 dgo[] = {
 854                0x0,
 855                0x10,
 856                0x20,
 857                0x30,
 858                0x40,
 859                0x50,
 860        };
 861
 862        /* Pins */
 863        printf("Pins:\n");
 864        for (idx = 0; idx < ARRAY_SIZE(pads); idx++) {
 865                u8 pad_id = pads[idx];
 866
 867                scierr = sc_pad_get(-1, pad_id, &data[0]);
 868                if (scierr == 0)
 869                        printf("\t- Pin %d: %.8x\n", pad_id, data[0]);
 870                else
 871                        printf("Failed to read Pin %d\n", pad_id);
 872        }
 873
 874        /* Fuses */
 875        printf("Fuses:\n");
 876        for (idx = 0; idx < ARRAY_SIZE(fuses); idx++) {
 877                u32 fuse_id = fuses[idx];
 878
 879                scierr = sc_misc_otp_fuse_read(-1, fuse_id, &data[0]);
 880                if (scierr == 0)
 881                        printf("\t- Fuse %d: %.8x\n", fuse_id, data[0]);
 882                else
 883                        printf("Failed to read Fuse %d\n", fuse_id);
 884        }
 885
 886        /* SNVS */
 887        printf("SNVS:\n");
 888        for (idx = 0; idx < ARRAY_SIZE(snvs); idx++) {
 889                struct snvs_reg *reg = &snvs[idx];
 890
 891                scierr = sc_seco_secvio_config(-1, reg->id, 0, &data[0],
 892                                               &data[1], &data[2], &data[3],
 893                                               &data[4], reg->nb);
 894                if (scierr == 0) {
 895                        int subidx;
 896
 897                        printf("\t- SNVS %.2x(%d):", reg->id, reg->nb);
 898                        for (subidx = 0; subidx < reg->nb; subidx++)
 899                                printf(" %.8x", data[subidx]);
 900                        printf("\n");
 901                } else {
 902                        printf("Failed to read SNVS %d\n", reg->id);
 903                }
 904        }
 905
 906        /* DGO */
 907        printf("DGO:\n");
 908        for (idx = 0; idx < ARRAY_SIZE(dgo); idx++) {
 909                u8 dgo_id = dgo[idx];
 910
 911                scierr = sc_seco_secvio_dgo_config(-1, dgo_id, 0, &data[0]);
 912                if (scierr == 0)
 913                        printf("\t- DGO %.2x: %.8x\n", dgo_id, data[0]);
 914                else
 915                        printf("Failed to read DGO %d\n", dgo_id);
 916        }
 917
 918        return 0;
 919}
 920
 921U_BOOT_CMD(snvs_sec_status,
 922           1, 1, do_snvs_sec_status,
 923           "tamper pin configuration",
 924           snvs_sec_status_help_text
 925);
 926