snvs_security_sc.c 23 KB

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