cmds.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * (C) Copyright 2018 Xilinx, Inc.
  4. * Siva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
  5. */
  6. #include <common.h>
  7. #include <malloc.h>
  8. #include <asm/arch/hardware.h>
  9. #include <asm/arch/sys_proto.h>
  10. #include <asm/io.h>
  11. static int do_zynqmp_verify_secure(cmd_tbl_t *cmdtp, int flag, int argc,
  12. char * const argv[])
  13. {
  14. u64 src_addr, addr;
  15. u32 len, src_lo, src_hi;
  16. u8 *key_ptr = NULL;
  17. int ret;
  18. u32 key_lo = 0;
  19. u32 key_hi = 0;
  20. u32 ret_payload[PAYLOAD_ARG_CNT];
  21. if (argc < 4)
  22. return CMD_RET_USAGE;
  23. src_addr = simple_strtoull(argv[2], NULL, 16);
  24. len = simple_strtoul(argv[3], NULL, 16);
  25. if (argc == 5)
  26. key_ptr = (uint8_t *)(uintptr_t)simple_strtoull(argv[4],
  27. NULL, 16);
  28. if ((ulong)src_addr != ALIGN((ulong)src_addr,
  29. CONFIG_SYS_CACHELINE_SIZE)) {
  30. printf("Failed: source address not aligned:%lx\n",
  31. (ulong)src_addr);
  32. return -EINVAL;
  33. }
  34. src_lo = lower_32_bits((ulong)src_addr);
  35. src_hi = upper_32_bits((ulong)src_addr);
  36. flush_dcache_range((ulong)src_addr, (ulong)(src_addr + len));
  37. if (key_ptr) {
  38. key_lo = lower_32_bits((ulong)key_ptr);
  39. key_hi = upper_32_bits((ulong)key_ptr);
  40. flush_dcache_range((ulong)key_ptr,
  41. (ulong)(key_ptr + KEY_PTR_LEN));
  42. }
  43. ret = invoke_smc(ZYNQMP_SIP_SVC_PM_SECURE_IMG_LOAD, src_lo, src_hi,
  44. key_lo, key_hi, ret_payload);
  45. if (ret) {
  46. printf("Failed: secure op status:0x%x\n", ret);
  47. } else {
  48. addr = (u64)ret_payload[1] << 32 | ret_payload[2];
  49. printf("Verified image at 0x%llx\n", addr);
  50. env_set_hex("zynqmp_verified_img_addr", addr);
  51. }
  52. return ret;
  53. }
  54. static int do_zynqmp_mmio_read(cmd_tbl_t *cmdtp, int flag, int argc,
  55. char * const argv[])
  56. {
  57. u32 read_val, addr;
  58. int ret;
  59. if (argc != cmdtp->maxargs)
  60. return CMD_RET_USAGE;
  61. addr = simple_strtoul(argv[2], NULL, 16);
  62. ret = zynqmp_mmio_read(addr, &read_val);
  63. if (!ret)
  64. printf("mmio read value at 0x%x = 0x%x\n",
  65. addr, read_val);
  66. else
  67. printf("Failed: mmio read\n");
  68. return ret;
  69. }
  70. static int do_zynqmp_mmio_write(cmd_tbl_t *cmdtp, int flag, int argc,
  71. char * const argv[])
  72. {
  73. u32 addr, mask, val;
  74. int ret;
  75. if (argc != cmdtp->maxargs)
  76. return CMD_RET_USAGE;
  77. addr = simple_strtoul(argv[2], NULL, 16);
  78. mask = simple_strtoul(argv[3], NULL, 16);
  79. val = simple_strtoul(argv[4], NULL, 16);
  80. ret = zynqmp_mmio_write(addr, mask, val);
  81. if (ret != 0)
  82. printf("Failed: mmio write\n");
  83. return ret;
  84. }
  85. #ifdef CONFIG_DEFINE_TCM_OCM_MMAP
  86. static int do_zynqmp_tcm_init(cmd_tbl_t *cmdtp, int flag, int argc,
  87. char * const argv[])
  88. {
  89. u8 mode;
  90. if (argc != cmdtp->maxargs)
  91. return CMD_RET_USAGE;
  92. mode = simple_strtoul(argv[2], NULL, 16);
  93. if (mode != TCM_LOCK && mode != TCM_SPLIT) {
  94. printf("Mode should be either 0(lock)/1(split)\n");
  95. return CMD_RET_FAILURE;
  96. }
  97. dcache_disable();
  98. tcm_init(mode);
  99. dcache_enable();
  100. return CMD_RET_SUCCESS;
  101. }
  102. #endif
  103. static cmd_tbl_t cmd_zynqmp_sub[] = {
  104. U_BOOT_CMD_MKENT(secure, 5, 0, do_zynqmp_verify_secure, "", ""),
  105. U_BOOT_CMD_MKENT(mmio_read, 3, 0, do_zynqmp_mmio_read, "", ""),
  106. U_BOOT_CMD_MKENT(mmio_write, 5, 0, do_zynqmp_mmio_write, "", ""),
  107. #ifdef CONFIG_DEFINE_TCM_OCM_MMAP
  108. U_BOOT_CMD_MKENT(tcminit, 3, 0, do_zynqmp_tcm_init, "", ""),
  109. #endif
  110. };
  111. /**
  112. * do_zynqmp - Handle the "zynqmp" command-line command
  113. * @cmdtp: Command data struct pointer
  114. * @flag: Command flag
  115. * @argc: Command-line argument count
  116. * @argv: Array of command-line arguments
  117. *
  118. * Processes the zynqmp specific commands
  119. *
  120. * Return: return 0 on success and CMD_RET_USAGE incase of misuse and error
  121. */
  122. static int do_zynqmp(cmd_tbl_t *cmdtp, int flag, int argc,
  123. char *const argv[])
  124. {
  125. cmd_tbl_t *c;
  126. if (argc < 2)
  127. return CMD_RET_USAGE;
  128. c = find_cmd_tbl(argv[1], &cmd_zynqmp_sub[0],
  129. ARRAY_SIZE(cmd_zynqmp_sub));
  130. if (c)
  131. return c->cmd(c, flag, argc, argv);
  132. else
  133. return CMD_RET_USAGE;
  134. }
  135. /***************************************************/
  136. #ifdef CONFIG_SYS_LONGHELP
  137. static char zynqmp_help_text[] =
  138. "secure src len [key_addr] - verifies secure images of $len bytes\n"
  139. " long at address $src. Optional key_addr\n"
  140. " can be specified if user key needs to\n"
  141. " be used for decryption\n"
  142. "zynqmp mmio_read address - read from address\n"
  143. "zynqmp mmio_write address mask value - write value after masking to\n"
  144. " address\n"
  145. #ifdef CONFIG_DEFINE_TCM_OCM_MMAP
  146. "zynqmp tcminit mode - Initialize the TCM with zeros. TCM needs to be\n"
  147. " initialized before accessing to avoid ECC\n"
  148. " errors. mode specifies in which mode TCM has\n"
  149. " to be initialized. Supported modes will be\n"
  150. " lock(0)/split(1)\n"
  151. #endif
  152. ;
  153. #endif
  154. U_BOOT_CMD(
  155. zynqmp, 5, 1, do_zynqmp,
  156. "ZynqMP sub-system",
  157. zynqmp_help_text
  158. )