mt_scp.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. #include <stdint.h>
  2. #include <string.h>
  3. #include <debug.h>
  4. #include <platform/boot_mode.h>
  5. #include <platform/partition.h>
  6. #include <platform/verified_boot.h>
  7. #include <platform/sec_policy.h>
  8. #ifdef DEVICE_TREE_SUPPORT
  9. #include <libfdt.h>
  10. #endif
  11. #include <platform/emi_mpu.h>
  12. #include <part_interface.h>
  13. #include <env.h>
  14. #define SCP_DRAM_SIZE 0x00200000 // mblock_reserve requires 2MB, SCP only requires 512KB
  15. #define DRAM_ADDR_MAX 0xBFFFFFFF // max address can SCP remap
  16. #define DRAM_4GB_MAX 0xFFFFFFFF
  17. #define DRAM_4GB_OFFSET 0x40000000
  18. #define SCP_EMI_REGION 2
  19. #define LOADER_NAME "tinysys-loader-CM4_A"
  20. #define FIRMWARE_NAME "tinysys-scp-CM4_A"
  21. extern u64 physical_memory_size(void);
  22. extern int mboot_common_load_part(char *part_name, char *img_name, unsigned long addr);
  23. extern int verify_load_scp_image(char *part_name, char *loader_name, char *firmware_name, void *addr, unsigned int offset);
  24. extern BOOT_ARGUMENT *g_boot_arg;
  25. static int load_scp_status = 0;
  26. static void *dram_addr;
  27. static char *scp_part_name[] = {"scp1", "scp2"};
  28. int load_scp_image(char *part_name, char *img_name, void *addr)
  29. {
  30. uint32_t sec_ret;
  31. uint32_t scp_vfy_time;
  32. int ret;
  33. #ifdef MTK_SECURITY_SW_SUPPORT
  34. unsigned int policy_entry_idx = 0;
  35. unsigned int img_auth_required = 0;
  36. policy_entry_idx = get_policy_entry_idx(part_name);
  37. img_auth_required = get_vfy_policy(policy_entry_idx);
  38. /* verify cert chain of boot img */
  39. if (img_auth_required) {
  40. scp_vfy_time = get_timer(0);
  41. sec_ret = sec_img_auth_init(part_name, img_name, 0);
  42. if (sec_ret)
  43. return -1;
  44. dprintf(DEBUG, "[SBC] scp cert vfy pass(%d ms)\n", (unsigned int)get_timer(scp_vfy_time));
  45. }
  46. #endif
  47. ret = mboot_common_load_part(part_name, img_name, addr);
  48. dprintf(INFO, "%s(): ret=%d\n", __func__, ret);
  49. if (ret <= 0)
  50. return -1;
  51. #ifdef MTK_SECURITY_SW_SUPPORT
  52. if (img_auth_required) {
  53. scp_vfy_time = get_timer(0);
  54. sec_ret = sec_img_auth(addr, ret);
  55. if (sec_ret)
  56. return -1;
  57. dprintf(DEBUG, "[SBC] scp vfy pass(%d ms)\n", (unsigned int)get_timer(scp_vfy_time));
  58. }
  59. #endif
  60. return ret;
  61. }
  62. static char *scp_partition_name(void)
  63. {
  64. int i;
  65. part_t *part;
  66. for (i = 0; i < (sizeof(scp_part_name) / sizeof(*scp_part_name)); i++) {
  67. if (partition_get_active_bit_by_name(scp_part_name[i]) == 1)
  68. return scp_part_name[i];
  69. }
  70. dprintf(CRITICAL, "no scp partition with active bit marked, load %s\n", scp_part_name[0]);
  71. return scp_part_name[0];
  72. }
  73. int load_scp(void)
  74. {
  75. int ret;
  76. unsigned int dram_ofs, perm;
  77. u64 dram_size;
  78. char *part_name;
  79. dram_addr = (void *) mblock_reserve(&g_boot_arg->mblock_info, SCP_DRAM_SIZE, 0x10000, DRAM_ADDR_MAX, RANKMAX);
  80. dprintf(INFO, "%s(): dram_addr=%p\n", __func__, dram_addr);
  81. if (dram_addr == ((void *) 0))
  82. goto error;
  83. dram_size = physical_memory_size();
  84. if (dram_size > DRAM_4GB_MAX)
  85. dram_ofs = DRAM_4GB_OFFSET;
  86. else
  87. dram_ofs = 0;
  88. part_name = scp_partition_name();
  89. if (part_name) {
  90. ret = verify_load_scp_image(part_name, LOADER_NAME, FIRMWARE_NAME, dram_addr, dram_ofs);
  91. if (ret < 0) {
  92. dprintf(CRITICAL, "scp verify %s failed, code=%d\n", part_name, ret);
  93. goto error;
  94. }
  95. } else {
  96. ret = -1;
  97. dprintf(CRITICAL, "get scp partition failed\n");
  98. goto error;
  99. }
  100. /*clean dcache & icache before set up EMI MPU*/
  101. arch_sync_cache_range((addr_t)dram_addr, SCP_DRAM_SIZE);
  102. /*
  103. * setup EMI MPU
  104. * domain 0: AP
  105. * domain 3: SCP
  106. */
  107. perm = SET_ACCESS_PERMISSON(UNLOCK, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION, FORBIDDEN, FORBIDDEN, SEC_RW);
  108. emi_mpu_set_region_protection(dram_addr, dram_addr + SCP_DRAM_SIZE - 1, SCP_EMI_REGION, perm);
  109. dprintf(INFO, "%s(): done\n", __func__);
  110. load_scp_status = 1;
  111. return 0;
  112. error:
  113. /*
  114. * @ret = 0, malloc() error
  115. * @ret < 0, error code from load_scp_image()
  116. */
  117. load_scp_status = ret;
  118. return -1;
  119. }
  120. #ifdef DEVICE_TREE_SUPPORT
  121. int platform_fdt_scp(void *fdt)
  122. {
  123. int nodeoffset;
  124. char *ret;
  125. dprintf(CRITICAL, "%s()\n", __func__);
  126. nodeoffset = fdt_node_offset_by_compatible(fdt, -1, "mediatek,scp");
  127. if (nodeoffset >= 0) {
  128. if (load_scp_status <= 0)
  129. ret = "fail";
  130. else
  131. ret = "okay";
  132. dprintf(CRITICAL, "status=%s\n", ret);
  133. fdt_setprop(fdt, nodeoffset, "status", ret, strlen(ret));
  134. return 0;
  135. }
  136. return 1;
  137. }
  138. #endif