1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2015, Linaro Limited 4 */ 5 #include <compiler.h> 6 #include <drivers/clk.h> 7 #include <drivers/regulator.h> 8 #include <kernel/pseudo_ta.h> 9 #include <kernel/tee_time.h> 10 #include <malloc.h> 11 #include <mm/phys_mem.h> 12 #include <mm/tee_mm.h> 13 #include <mm/tee_pager.h> 14 #include <pta_stats.h> 15 #include <string.h> 16 #include <string_ext.h> 17 #include <tee_api_types.h> 18 #include <trace.h> 19 20 static TEE_Result get_alloc_stats(uint32_t type, TEE_Param p[TEE_NUM_PARAMS]) 21 { 22 struct pta_stats_alloc *stats = NULL; 23 uint32_t size_to_retrieve = 0; 24 uint32_t pool_id = 0; 25 uint32_t i = 0; 26 27 /* 28 * p[0].value.a = pool id (from 0 to n) 29 * - 0 means all the pools to be retrieved 30 * - 1..n means pool id 31 * p[0].value.b = 0 if no reset of the stats 32 * p[1].memref.buffer = output buffer to struct pta_stats_alloc 33 */ 34 if (TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 35 TEE_PARAM_TYPE_MEMREF_OUTPUT, 36 TEE_PARAM_TYPE_NONE, 37 TEE_PARAM_TYPE_NONE) != type) { 38 return TEE_ERROR_BAD_PARAMETERS; 39 } 40 41 pool_id = p[0].value.a; 42 if (pool_id > STATS_NB_POOLS) 43 return TEE_ERROR_BAD_PARAMETERS; 44 45 size_to_retrieve = sizeof(struct pta_stats_alloc); 46 if (pool_id == ALLOC_ID_ALL) 47 size_to_retrieve *= STATS_NB_POOLS; 48 49 if (p[1].memref.size < size_to_retrieve) { 50 p[1].memref.size = size_to_retrieve; 51 return TEE_ERROR_SHORT_BUFFER; 52 } 53 p[1].memref.size = size_to_retrieve; 54 stats = p[1].memref.buffer; 55 56 for (i = ALLOC_ID_HEAP; i <= STATS_NB_POOLS; i++) { 57 if (pool_id != ALLOC_ID_ALL && i != pool_id) 58 continue; 59 60 switch (i) { 61 case ALLOC_ID_HEAP: 62 malloc_get_stats(stats); 63 strlcpy(stats->desc, "Heap", sizeof(stats->desc)); 64 if (p[0].value.b) 65 malloc_reset_stats(); 66 break; 67 68 case ALLOC_ID_PUBLIC_DDR: 69 EMSG("public DDR not managed by secure side anymore"); 70 break; 71 72 case ALLOC_ID_TA_RAM: 73 phys_mem_stats(stats, p[0].value.b); 74 strlcpy(stats->desc, "Physical TA memory", 75 sizeof(stats->desc)); 76 break; 77 78 #ifdef CFG_NS_VIRTUALIZATION 79 case ALLOC_ID_NEXUS_HEAP: 80 nex_malloc_get_stats(stats); 81 strlcpy(stats->desc, "KHeap", sizeof(stats->desc)); 82 if (p[0].value.b) 83 nex_malloc_reset_stats(); 84 break; 85 #endif 86 default: 87 EMSG("Wrong pool id"); 88 break; 89 } 90 91 stats++; 92 } 93 94 return TEE_SUCCESS; 95 } 96 97 static TEE_Result get_pager_stats(uint32_t type, TEE_Param p[TEE_NUM_PARAMS]) 98 { 99 struct tee_pager_stats stats = { }; 100 101 if (TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT, 102 TEE_PARAM_TYPE_VALUE_OUTPUT, 103 TEE_PARAM_TYPE_VALUE_OUTPUT, 104 TEE_PARAM_TYPE_NONE) != type) { 105 EMSG("expect 3 output values as argument"); 106 return TEE_ERROR_BAD_PARAMETERS; 107 } 108 109 tee_pager_get_stats(&stats); 110 p[0].value.a = stats.npages; 111 p[0].value.b = stats.npages_all; 112 p[1].value.a = stats.ro_hits; 113 p[1].value.b = stats.rw_hits; 114 p[2].value.a = stats.hidden_hits; 115 p[2].value.b = stats.zi_released; 116 117 return TEE_SUCCESS; 118 } 119 120 static TEE_Result get_memleak_stats(uint32_t type, 121 TEE_Param p[TEE_NUM_PARAMS] __maybe_unused) 122 { 123 124 if (TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE, 125 TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE) != type) 126 return TEE_ERROR_BAD_PARAMETERS; 127 128 mdbg_check(1); 129 130 return TEE_SUCCESS; 131 } 132 133 static TEE_Result get_user_ta_stats(uint32_t type, 134 TEE_Param p[TEE_NUM_PARAMS] __maybe_unused) 135 { 136 uint32_t res = TEE_SUCCESS; 137 138 if (TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_OUTPUT, 139 TEE_PARAM_TYPE_NONE, 140 TEE_PARAM_TYPE_NONE, 141 TEE_PARAM_TYPE_NONE) != type) 142 return TEE_ERROR_BAD_PARAMETERS; 143 144 #if defined(CFG_TA_STATS) 145 res = tee_ta_instance_stats(p[0].memref.buffer, 146 &p[0].memref.size); 147 if (res != TEE_SUCCESS) 148 DMSG("tee_ta_dump_stats return: 0x%"PRIx32, res); 149 #else 150 res = TEE_ERROR_NOT_SUPPORTED; 151 #endif 152 return res; 153 } 154 155 static TEE_Result get_system_time(uint32_t type, 156 TEE_Param p[TEE_NUM_PARAMS]) 157 { 158 TEE_Result ret = TEE_ERROR_GENERIC; 159 TEE_Time ree_time = { }; 160 TEE_Time tee_time = { }; 161 162 if (TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT, 163 TEE_PARAM_TYPE_VALUE_OUTPUT, 164 TEE_PARAM_TYPE_NONE, 165 TEE_PARAM_TYPE_NONE) != type) 166 return TEE_ERROR_BAD_PARAMETERS; 167 168 ret = tee_time_get_sys_time(&tee_time); 169 if (ret) 170 return ret; 171 172 ret = tee_time_get_ree_time(&ree_time); 173 if (ret) 174 return ret; 175 176 p[0].value.a = ree_time.seconds; 177 p[0].value.b = ree_time.millis; 178 p[1].value.a = tee_time.seconds; 179 p[1].value.b = tee_time.millis; 180 181 return TEE_SUCCESS; 182 } 183 184 static TEE_Result print_driver_info(uint32_t type, TEE_Param p[TEE_NUM_PARAMS]) 185 { 186 if (TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 187 TEE_PARAM_TYPE_NONE, 188 TEE_PARAM_TYPE_NONE, 189 TEE_PARAM_TYPE_NONE) != type) 190 return TEE_ERROR_BAD_PARAMETERS; 191 192 switch (p[0].value.a) { 193 case STATS_DRIVER_TYPE_CLOCK: 194 clk_print_tree(); 195 break; 196 case STATS_DRIVER_TYPE_REGULATOR: 197 regulator_print_tree(); 198 break; 199 default: 200 return TEE_ERROR_BAD_PARAMETERS; 201 } 202 203 return TEE_SUCCESS; 204 } 205 206 /* 207 * Trusted Application Entry Points 208 */ 209 210 static TEE_Result invoke_command(void *psess __unused, 211 uint32_t cmd, uint32_t ptypes, 212 TEE_Param params[TEE_NUM_PARAMS]) 213 { 214 switch (cmd) { 215 case STATS_CMD_PAGER_STATS: 216 return get_pager_stats(ptypes, params); 217 case STATS_CMD_ALLOC_STATS: 218 return get_alloc_stats(ptypes, params); 219 case STATS_CMD_MEMLEAK_STATS: 220 return get_memleak_stats(ptypes, params); 221 case STATS_CMD_TA_STATS: 222 return get_user_ta_stats(ptypes, params); 223 case STATS_CMD_GET_TIME: 224 return get_system_time(ptypes, params); 225 case STATS_CMD_PRINT_DRIVER_INFO: 226 return print_driver_info(ptypes, params); 227 default: 228 break; 229 } 230 return TEE_ERROR_BAD_PARAMETERS; 231 } 232 233 pseudo_ta_register(.uuid = STATS_UUID, .name = "stats.pta", 234 .flags = PTA_DEFAULT_FLAGS, 235 .invoke_command_entry_point = invoke_command); 236