context_debug.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /*
  2. * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <string.h>
  7. #include <common/debug.h>
  8. #include <context.h>
  9. #include <lib/el3_runtime/context_mgmt.h>
  10. #include <lib/el3_runtime/cpu_data.h>
  11. /********************************************************************************
  12. * Function that returns the corresponding string constant for a security state
  13. * index.
  14. *******************************************************************************/
  15. static const char *get_context_name_by_idx(unsigned int security_state_idx)
  16. {
  17. assert(security_state_idx < CPU_CONTEXT_NUM);
  18. static const char * const state_names[] = {
  19. "Secure",
  20. "Non Secure"
  21. #if ENABLE_RME
  22. , "Realm"
  23. #endif /* ENABLE_RME */
  24. };
  25. return state_names[security_state_idx];
  26. }
  27. #define PRINT_MEM_USAGE_SEPARATOR() \
  28. do { \
  29. printf("+-----------+-----------+-----------" \
  30. "+-----------+-----------+-----------+\n"); \
  31. } while (false)
  32. #define NAME_PLACEHOLDER_LEN 14
  33. #define PRINT_DASH(n) \
  34. for (; n > 0; n--) { \
  35. putchar('-'); \
  36. }
  37. #define PRINT_SINGLE_MEM_USAGE_SEP_BLOCK() \
  38. do { \
  39. printf("+-----------"); \
  40. } while (false)
  41. /********************************************************************************
  42. * This function prints the allocated memory for a specific security state.
  43. * Values are grouped by exception level and core. The memory usage for the
  44. * global context and the total memory for the security state are also computed.
  45. *******************************************************************************/
  46. static size_t report_allocated_memory(unsigned int security_state_idx)
  47. {
  48. size_t core_total = 0U;
  49. size_t gp_total = 0U;
  50. size_t el3_total = 0U;
  51. size_t other_total = 0U;
  52. size_t total = 0U;
  53. size_t per_world_ctx_size = 0U;
  54. #if CTX_INCLUDE_EL2_REGS
  55. size_t el2_total = 0U;
  56. #else
  57. size_t el1_total = 0U;
  58. #endif /* CTX_INCLUDE_EL2_REGS */
  59. #if CTX_INCLUDE_PAUTH_REGS
  60. size_t pauth_total = 0U;
  61. PRINT_SINGLE_MEM_USAGE_SEP_BLOCK();
  62. #endif
  63. PRINT_MEM_USAGE_SEPARATOR();
  64. printf("| Core | GP | EL3 ");
  65. #if CTX_INCLUDE_EL2_REGS
  66. printf("| EL2 ");
  67. #else
  68. printf("| EL1 ");
  69. #endif /* CTX_INCLUDE_EL2_REGS */
  70. #if CTX_INCLUDE_PAUTH_REGS
  71. printf("| PAUTH ");
  72. #endif
  73. printf("| Other | Total |\n");
  74. /* Compute memory usage for each core's context */
  75. for (unsigned int i = 0U; i < PLATFORM_CORE_COUNT; i++) {
  76. size_t size_other = 0U;
  77. size_t el3_size = 0U;
  78. size_t gp_size = 0U;
  79. #if CTX_INCLUDE_EL2_REGS
  80. size_t el2_size = 0U;
  81. #else
  82. size_t el1_size = 0U;
  83. #endif /* CTX_INCLUDE_EL2_REGS */
  84. #if CTX_INCLUDE_PAUTH_REGS
  85. size_t pauth_size = 0U;
  86. PRINT_SINGLE_MEM_USAGE_SEP_BLOCK();
  87. #endif
  88. PRINT_MEM_USAGE_SEPARATOR();
  89. cpu_context_t *ctx = (cpu_context_t *)cm_get_context_by_index(i,
  90. security_state_idx);
  91. core_total = sizeof(*ctx);
  92. el3_size = sizeof(ctx->el3state_ctx);
  93. gp_size = sizeof(ctx->gpregs_ctx);
  94. size_other = core_total - (el3_size + gp_size);
  95. printf("| %9u | %8luB | %8luB ", i, gp_size, el3_size);
  96. #if CTX_INCLUDE_EL2_REGS
  97. el2_size = sizeof(ctx->el2_sysregs_ctx);
  98. size_other -= el2_size;
  99. el2_total += el2_size;
  100. printf("| %8luB ", el2_size);
  101. #else
  102. el1_size = sizeof(ctx->el1_sysregs_ctx);
  103. size_other -= el1_size;
  104. el1_total += el1_size;
  105. printf("| %8luB ", el1_size);
  106. #endif /* CTX_INCLUDE_EL2_REGS */
  107. #if CTX_INCLUDE_PAUTH_REGS
  108. pauth_size = sizeof(ctx->pauth_ctx);
  109. size_other -= pauth_size;
  110. pauth_total += pauth_size;
  111. printf("| %8luB ", pauth_size);
  112. #endif
  113. printf("| %8luB | %8luB |\n", size_other, core_total);
  114. gp_total += gp_size;
  115. el3_total += el3_size;
  116. other_total += size_other;
  117. total += core_total;
  118. }
  119. #if CTX_INCLUDE_PAUTH_REGS
  120. PRINT_SINGLE_MEM_USAGE_SEP_BLOCK();
  121. #endif
  122. PRINT_MEM_USAGE_SEPARATOR();
  123. #if CTX_INCLUDE_PAUTH_REGS
  124. PRINT_SINGLE_MEM_USAGE_SEP_BLOCK();
  125. #endif
  126. PRINT_MEM_USAGE_SEPARATOR();
  127. printf("| All | %8luB | %8luB ", gp_total, el3_total);
  128. #if CTX_INCLUDE_EL2_REGS
  129. printf("| %8luB ", el2_total);
  130. #else
  131. printf("| %8luB ", el1_total);
  132. #endif /* CTX_INCLUDE_EL2_REGS */
  133. #if CTX_INCLUDE_PAUTH_REGS
  134. printf("| %8luB ", pauth_total);
  135. #endif
  136. printf("| %8luB | %8luB |\n", other_total, total);
  137. #if CTX_INCLUDE_PAUTH_REGS
  138. PRINT_SINGLE_MEM_USAGE_SEP_BLOCK();
  139. #endif
  140. PRINT_MEM_USAGE_SEPARATOR();
  141. printf("\n");
  142. /* Compute memory usage for the global context */
  143. per_world_ctx_size = sizeof(per_world_context[security_state_idx]);
  144. total += per_world_ctx_size;
  145. printf("Per-world context: %luB\n\n", per_world_ctx_size);
  146. printf("TOTAL: %luB\n", total);
  147. return total;
  148. }
  149. /********************************************************************************
  150. * Reports the allocated memory for every security state and then reports the
  151. * total system-wide allocated memory.
  152. *******************************************************************************/
  153. void report_ctx_memory_usage(void)
  154. {
  155. INFO("Context memory allocation:\n");
  156. size_t total = 0U;
  157. for (unsigned int i = 0U; i < CPU_CONTEXT_NUM; i++) {
  158. const char *context_name = get_context_name_by_idx(i);
  159. size_t len = 0U;
  160. printf("Memory usage for %s:\n", context_name);
  161. total += report_allocated_memory(i);
  162. printf("------------------------");
  163. len = NAME_PLACEHOLDER_LEN - printf("End %s", context_name);
  164. PRINT_DASH(len);
  165. printf("-----------------------\n\n");
  166. }
  167. printf("Total context memory allocated: %luB\n\n", total);
  168. }