ele_api.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright 2020, 2023 NXP
  4. *
  5. */
  6. #include <common.h>
  7. #include <hang.h>
  8. #include <malloc.h>
  9. #include <asm/io.h>
  10. #include <dm.h>
  11. #include <asm/mach-imx/ele_api.h>
  12. #include <misc.h>
  13. DECLARE_GLOBAL_DATA_PTR;
  14. static u32 compute_crc(const struct ele_msg *msg)
  15. {
  16. u32 crc = 0;
  17. size_t i = 0;
  18. u32 *data = (u32 *)msg;
  19. for (i = 0; i < (msg->size - 1); i++)
  20. crc ^= data[i];
  21. return crc;
  22. }
  23. int ele_release_rdc(u8 core_id, u8 xrdc, u32 *response)
  24. {
  25. struct udevice *dev = gd->arch.ele_dev;
  26. int size = sizeof(struct ele_msg);
  27. struct ele_msg msg;
  28. int ret;
  29. if (!dev) {
  30. printf("ele dev is not initialized\n");
  31. return -ENODEV;
  32. }
  33. msg.version = ELE_VERSION;
  34. msg.tag = ELE_CMD_TAG;
  35. msg.size = 2;
  36. msg.command = ELE_RELEASE_RDC_REQ;
  37. switch (xrdc) {
  38. case 0:
  39. msg.data[0] = (0x74 << 8) | core_id;
  40. break;
  41. case 1:
  42. msg.data[0] = (0x78 << 8) | core_id;
  43. break;
  44. case 2:
  45. msg.data[0] = (0x82 << 8) | core_id;
  46. break;
  47. case 3:
  48. msg.data[0] = (0x86 << 8) | core_id;
  49. break;
  50. default:
  51. printf("Error: wrong xrdc index %u\n", xrdc);
  52. return -EINVAL;
  53. }
  54. ret = misc_call(dev, false, &msg, size, &msg, size);
  55. if (ret)
  56. printf("Error: %s: ret %d, core id %u, response 0x%x\n",
  57. __func__, ret, core_id, msg.data[0]);
  58. if (response)
  59. *response = msg.data[0];
  60. return ret;
  61. }
  62. int ele_auth_oem_ctnr(ulong ctnr_addr, u32 *response)
  63. {
  64. struct udevice *dev = gd->arch.ele_dev;
  65. int size = sizeof(struct ele_msg);
  66. struct ele_msg msg;
  67. int ret;
  68. if (!dev) {
  69. printf("ele dev is not initialized\n");
  70. return -ENODEV;
  71. }
  72. msg.version = ELE_VERSION;
  73. msg.tag = ELE_CMD_TAG;
  74. msg.size = 3;
  75. msg.command = ELE_OEM_CNTN_AUTH_REQ;
  76. msg.data[0] = upper_32_bits(ctnr_addr);
  77. msg.data[1] = lower_32_bits(ctnr_addr);
  78. ret = misc_call(dev, false, &msg, size, &msg, size);
  79. if (ret)
  80. printf("Error: %s: ret %d, cntr_addr 0x%lx, response 0x%x\n",
  81. __func__, ret, ctnr_addr, msg.data[0]);
  82. if (response)
  83. *response = msg.data[0];
  84. return ret;
  85. }
  86. int ele_release_container(u32 *response)
  87. {
  88. struct udevice *dev = gd->arch.ele_dev;
  89. int size = sizeof(struct ele_msg);
  90. struct ele_msg msg;
  91. int ret;
  92. if (!dev) {
  93. printf("ele dev is not initialized\n");
  94. return -ENODEV;
  95. }
  96. msg.version = ELE_VERSION;
  97. msg.tag = ELE_CMD_TAG;
  98. msg.size = 1;
  99. msg.command = ELE_RELEASE_CONTAINER_REQ;
  100. ret = misc_call(dev, false, &msg, size, &msg, size);
  101. if (ret)
  102. printf("Error: %s: ret %d, response 0x%x\n",
  103. __func__, ret, msg.data[0]);
  104. if (response)
  105. *response = msg.data[0];
  106. return ret;
  107. }
  108. int ele_verify_image(u32 img_id, u32 *response)
  109. {
  110. struct udevice *dev = gd->arch.ele_dev;
  111. int size = sizeof(struct ele_msg);
  112. struct ele_msg msg;
  113. int ret;
  114. if (!dev) {
  115. printf("ele dev is not initialized\n");
  116. return -ENODEV;
  117. }
  118. msg.version = ELE_VERSION;
  119. msg.tag = ELE_CMD_TAG;
  120. msg.size = 2;
  121. msg.command = ELE_VERIFY_IMAGE_REQ;
  122. msg.data[0] = 1 << img_id;
  123. ret = misc_call(dev, false, &msg, size, &msg, size);
  124. if (ret)
  125. printf("Error: %s: ret %d, img_id %u, response 0x%x\n",
  126. __func__, ret, img_id, msg.data[0]);
  127. if (response)
  128. *response = msg.data[0];
  129. return ret;
  130. }
  131. int ele_forward_lifecycle(u16 life_cycle, u32 *response)
  132. {
  133. struct udevice *dev = gd->arch.ele_dev;
  134. int size = sizeof(struct ele_msg);
  135. struct ele_msg msg;
  136. int ret;
  137. if (!dev) {
  138. printf("ele dev is not initialized\n");
  139. return -ENODEV;
  140. }
  141. msg.version = ELE_VERSION;
  142. msg.tag = ELE_CMD_TAG;
  143. msg.size = 2;
  144. msg.command = ELE_FWD_LIFECYCLE_UP_REQ;
  145. msg.data[0] = life_cycle;
  146. ret = misc_call(dev, false, &msg, size, &msg, size);
  147. if (ret)
  148. printf("Error: %s: ret %d, life_cycle 0x%x, response 0x%x\n",
  149. __func__, ret, life_cycle, msg.data[0]);
  150. if (response)
  151. *response = msg.data[0];
  152. return ret;
  153. }
  154. int ele_read_common_fuse(u16 fuse_id, u32 *fuse_words, u32 fuse_num, u32 *response)
  155. {
  156. struct udevice *dev = gd->arch.ele_dev;
  157. int size = sizeof(struct ele_msg);
  158. struct ele_msg msg;
  159. int ret;
  160. if (!dev) {
  161. printf("ele dev is not initialized\n");
  162. return -ENODEV;
  163. }
  164. if (!fuse_words) {
  165. printf("Invalid parameters for fuse read\n");
  166. return -EINVAL;
  167. }
  168. if ((fuse_id != 1 && fuse_num != 1) ||
  169. (fuse_id == 1 && fuse_num != 4)) {
  170. printf("Invalid fuse number parameter\n");
  171. return -EINVAL;
  172. }
  173. msg.version = ELE_VERSION;
  174. msg.tag = ELE_CMD_TAG;
  175. msg.size = 2;
  176. msg.command = ELE_READ_FUSE_REQ;
  177. msg.data[0] = fuse_id;
  178. ret = misc_call(dev, false, &msg, size, &msg, size);
  179. if (ret)
  180. printf("Error: %s: ret %d, fuse_id 0x%x, response 0x%x\n",
  181. __func__, ret, fuse_id, msg.data[0]);
  182. if (response)
  183. *response = msg.data[0];
  184. fuse_words[0] = msg.data[1];
  185. if (fuse_id == 1) {
  186. /* OTP_UNIQ_ID */
  187. fuse_words[1] = msg.data[2];
  188. fuse_words[2] = msg.data[3];
  189. fuse_words[3] = msg.data[4];
  190. }
  191. return ret;
  192. }
  193. int ele_write_fuse(u16 fuse_id, u32 fuse_val, bool lock, u32 *response)
  194. {
  195. struct udevice *dev = gd->arch.ele_dev;
  196. int size = sizeof(struct ele_msg);
  197. struct ele_msg msg;
  198. int ret;
  199. if (!dev) {
  200. printf("ele dev is not initialized\n");
  201. return -ENODEV;
  202. }
  203. msg.version = ELE_VERSION;
  204. msg.tag = ELE_CMD_TAG;
  205. msg.size = 3;
  206. msg.command = ELE_WRITE_FUSE_REQ;
  207. msg.data[0] = (32 << 16) | (fuse_id << 5);
  208. if (lock)
  209. msg.data[0] |= (1 << 31);
  210. msg.data[1] = fuse_val;
  211. ret = misc_call(dev, false, &msg, size, &msg, size);
  212. if (ret)
  213. printf("Error: %s: ret %d, fuse_id 0x%x, response 0x%x\n",
  214. __func__, ret, fuse_id, msg.data[0]);
  215. if (response)
  216. *response = msg.data[0];
  217. return ret;
  218. }
  219. int ele_release_caam(u32 core_did, u32 *response)
  220. {
  221. struct udevice *dev = gd->arch.ele_dev;
  222. int size = sizeof(struct ele_msg);
  223. struct ele_msg msg;
  224. int ret;
  225. if (!dev) {
  226. printf("ele dev is not initialized\n");
  227. return -ENODEV;
  228. }
  229. msg.version = ELE_VERSION;
  230. msg.tag = ELE_CMD_TAG;
  231. msg.size = 2;
  232. msg.command = ELE_RELEASE_CAAM_REQ;
  233. msg.data[0] = core_did;
  234. ret = misc_call(dev, false, &msg, size, &msg, size);
  235. if (ret)
  236. printf("Error: %s: ret %d, response 0x%x\n",
  237. __func__, ret, msg.data[0]);
  238. if (response)
  239. *response = msg.data[0];
  240. return ret;
  241. }
  242. int ele_get_fw_version(u32 *fw_version, u32 *sha1, u32 *response)
  243. {
  244. struct udevice *dev = gd->arch.ele_dev;
  245. int size = sizeof(struct ele_msg);
  246. struct ele_msg msg;
  247. int ret;
  248. if (!dev) {
  249. printf("ele dev is not initialized\n");
  250. return -ENODEV;
  251. }
  252. if (!fw_version) {
  253. printf("Invalid parameters for f/w version read\n");
  254. return -EINVAL;
  255. }
  256. if (!sha1) {
  257. printf("Invalid parameters for commit sha1\n");
  258. return -EINVAL;
  259. }
  260. msg.version = ELE_VERSION;
  261. msg.tag = ELE_CMD_TAG;
  262. msg.size = 1;
  263. msg.command = ELE_GET_FW_VERSION_REQ;
  264. ret = misc_call(dev, false, &msg, size, &msg, size);
  265. if (ret)
  266. printf("Error: %s: ret %d, response 0x%x\n",
  267. __func__, ret, msg.data[0]);
  268. if (response)
  269. *response = msg.data[0];
  270. *fw_version = msg.data[1];
  271. *sha1 = msg.data[2];
  272. return ret;
  273. }
  274. int ele_dump_buffer(u32 *buffer, u32 buffer_length)
  275. {
  276. struct udevice *dev = gd->arch.ele_dev;
  277. int size = sizeof(struct ele_msg);
  278. struct ele_msg msg;
  279. int ret, i = 0;
  280. if (!dev) {
  281. printf("ele dev is not initialized\n");
  282. return -ENODEV;
  283. }
  284. msg.version = ELE_VERSION;
  285. msg.tag = ELE_CMD_TAG;
  286. msg.size = 1;
  287. msg.command = ELE_DUMP_DEBUG_BUFFER_REQ;
  288. ret = misc_call(dev, false, &msg, size, &msg, size);
  289. if (ret) {
  290. printf("Error: %s: ret %d, response 0x%x\n",
  291. __func__, ret, msg.data[0]);
  292. return ret;
  293. }
  294. if (buffer) {
  295. buffer[i++] = *(u32 *)&msg; /* Need dump the response header */
  296. for (; i < buffer_length && i < msg.size; i++)
  297. buffer[i] = msg.data[i - 1];
  298. }
  299. return i;
  300. }
  301. int ele_get_info(struct ele_get_info_data *info, u32 *response)
  302. {
  303. struct udevice *dev = gd->arch.ele_dev;
  304. int size = sizeof(struct ele_msg);
  305. struct ele_msg msg;
  306. int ret;
  307. if (!dev) {
  308. printf("ele dev is not initialized\n");
  309. return -ENODEV;
  310. }
  311. msg.version = ELE_VERSION;
  312. msg.tag = ELE_CMD_TAG;
  313. msg.size = 4;
  314. msg.command = ELE_GET_INFO_REQ;
  315. msg.data[0] = upper_32_bits((ulong)info);
  316. msg.data[1] = lower_32_bits((ulong)info);
  317. msg.data[2] = sizeof(struct ele_get_info_data);
  318. ret = misc_call(dev, false, &msg, size, &msg, size);
  319. if (ret)
  320. printf("Error: %s: ret %d, response 0x%x\n",
  321. __func__, ret, msg.data[0]);
  322. if (response)
  323. *response = msg.data[0];
  324. return ret;
  325. }
  326. int ele_get_fw_status(u32 *status, u32 *response)
  327. {
  328. struct udevice *dev = gd->arch.ele_dev;
  329. int size = sizeof(struct ele_msg);
  330. struct ele_msg msg;
  331. int ret;
  332. if (!dev) {
  333. printf("ele dev is not initialized\n");
  334. return -ENODEV;
  335. }
  336. msg.version = ELE_VERSION;
  337. msg.tag = ELE_CMD_TAG;
  338. msg.size = 1;
  339. msg.command = ELE_GET_FW_STATUS_REQ;
  340. ret = misc_call(dev, false, &msg, size, &msg, size);
  341. if (ret)
  342. printf("Error: %s: ret %d, response 0x%x\n",
  343. __func__, ret, msg.data[0]);
  344. if (response)
  345. *response = msg.data[0];
  346. *status = msg.data[1] & 0xF;
  347. return ret;
  348. }
  349. int ele_release_m33_trout(void)
  350. {
  351. struct udevice *dev = gd->arch.ele_dev;
  352. int size = sizeof(struct ele_msg);
  353. struct ele_msg msg;
  354. int ret;
  355. if (!dev) {
  356. printf("ele dev is not initialized\n");
  357. return -ENODEV;
  358. }
  359. msg.version = ELE_VERSION;
  360. msg.tag = ELE_CMD_TAG;
  361. msg.size = 1;
  362. msg.command = ELE_ENABLE_RTC_REQ;
  363. ret = misc_call(dev, false, &msg, size, &msg, size);
  364. if (ret)
  365. printf("Error: %s: ret %d, response 0x%x\n",
  366. __func__, ret, msg.data[0]);
  367. return ret;
  368. }
  369. int ele_get_events(u32 *events, u32 *events_cnt, u32 *response)
  370. {
  371. struct udevice *dev = gd->arch.ele_dev;
  372. int size = sizeof(struct ele_msg);
  373. struct ele_msg msg;
  374. int ret, i = 0;
  375. u32 actual_events;
  376. if (!dev) {
  377. printf("ele dev is not initialized\n");
  378. return -ENODEV;
  379. }
  380. if (!events || !events_cnt || *events_cnt == 0) {
  381. printf("Invalid parameters for %s\n", __func__);
  382. return -EINVAL;
  383. }
  384. msg.version = ELE_VERSION;
  385. msg.tag = ELE_CMD_TAG;
  386. msg.size = 1;
  387. msg.command = ELE_GET_EVENTS_REQ;
  388. ret = misc_call(dev, false, &msg, size, &msg, size);
  389. if (ret)
  390. printf("Error: %s: ret %d, response 0x%x\n",
  391. __func__, ret, msg.data[0]);
  392. if (response)
  393. *response = msg.data[0];
  394. if (!ret) {
  395. actual_events = msg.data[1] & 0xffff;
  396. if (*events_cnt < actual_events)
  397. actual_events = *events_cnt;
  398. for (; i < actual_events; i++)
  399. events[i] = msg.data[i + 2];
  400. *events_cnt = actual_events;
  401. }
  402. return ret;
  403. }
  404. int ele_start_rng(void)
  405. {
  406. struct udevice *dev = gd->arch.ele_dev;
  407. int size = sizeof(struct ele_msg);
  408. struct ele_msg msg;
  409. int ret;
  410. if (!dev) {
  411. printf("ele dev is not initialized\n");
  412. return -ENODEV;
  413. }
  414. msg.version = ELE_VERSION;
  415. msg.tag = ELE_CMD_TAG;
  416. msg.size = 1;
  417. msg.command = ELE_START_RNG;
  418. ret = misc_call(dev, false, &msg, size, &msg, size);
  419. if (ret)
  420. printf("Error: %s: ret %d, response 0x%x\n",
  421. __func__, ret, msg.data[0]);
  422. return ret;
  423. }
  424. int ele_write_secure_fuse(ulong signed_msg_blk, u32 *response)
  425. {
  426. struct udevice *dev = gd->arch.ele_dev;
  427. int size = sizeof(struct ele_msg);
  428. struct ele_msg msg;
  429. int ret;
  430. if (!dev) {
  431. printf("ele dev is not initialized\n");
  432. return -ENODEV;
  433. }
  434. msg.version = ELE_VERSION;
  435. msg.tag = ELE_CMD_TAG;
  436. msg.size = 3;
  437. msg.command = ELE_WRITE_SECURE_FUSE_REQ;
  438. msg.data[0] = upper_32_bits(signed_msg_blk);
  439. msg.data[1] = lower_32_bits(signed_msg_blk);
  440. ret = misc_call(dev, false, &msg, size, &msg, size);
  441. if (ret)
  442. printf("Error: %s: ret %d, response 0x%x, failed fuse row index %u\n",
  443. __func__, ret, msg.data[0], msg.data[1]);
  444. if (response)
  445. *response = msg.data[0];
  446. return ret;
  447. }
  448. int ele_return_lifecycle_update(ulong signed_msg_blk, u32 *response)
  449. {
  450. struct udevice *dev = gd->arch.ele_dev;
  451. int size = sizeof(struct ele_msg);
  452. struct ele_msg msg;
  453. int ret;
  454. if (!dev) {
  455. printf("ele dev is not initialized\n");
  456. return -ENODEV;
  457. }
  458. msg.version = ELE_VERSION;
  459. msg.tag = ELE_CMD_TAG;
  460. msg.size = 3;
  461. msg.command = ELE_RET_LIFECYCLE_UP_REQ;
  462. msg.data[0] = upper_32_bits(signed_msg_blk);
  463. msg.data[1] = lower_32_bits(signed_msg_blk);
  464. ret = misc_call(dev, false, &msg, size, &msg, size);
  465. if (ret)
  466. printf("Error: %s: ret %d, response 0x%x, failed fuse row index %u\n",
  467. __func__, ret, msg.data[0], msg.data[1]);
  468. if (response)
  469. *response = msg.data[0];
  470. return ret;
  471. }
  472. int ele_generate_dek_blob(u32 key_id, u32 src_paddr, u32 dst_paddr, u32 max_output_size)
  473. {
  474. struct udevice *dev = gd->arch.ele_dev;
  475. int size = sizeof(struct ele_msg);
  476. struct ele_msg msg;
  477. int ret;
  478. if (!dev) {
  479. printf("ele dev is not initialized\n");
  480. return -ENODEV;
  481. }
  482. msg.version = ELE_VERSION;
  483. msg.tag = ELE_CMD_TAG;
  484. msg.size = 8;
  485. msg.command = ELE_GENERATE_DEK_BLOB;
  486. msg.data[0] = key_id;
  487. msg.data[1] = 0x0;
  488. msg.data[2] = src_paddr;
  489. msg.data[3] = 0x0;
  490. msg.data[4] = dst_paddr;
  491. msg.data[5] = max_output_size;
  492. msg.data[6] = compute_crc(&msg);
  493. ret = misc_call(dev, false, &msg, size, &msg, size);
  494. if (ret)
  495. printf("Error: %s: ret 0x%x, response 0x%x\n",
  496. __func__, ret, msg.data[0]);
  497. return ret;
  498. }