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