summaryrefslogtreecommitdiff
path: root/core/arch/arm/pta/stats.c
diff options
context:
space:
mode:
Diffstat (limited to 'core/arch/arm/pta/stats.c')
-rw-r--r--core/arch/arm/pta/stats.c161
1 files changed, 161 insertions, 0 deletions
diff --git a/core/arch/arm/pta/stats.c b/core/arch/arm/pta/stats.c
new file mode 100644
index 0000000..408c284
--- /dev/null
+++ b/core/arch/arm/pta/stats.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <compiler.h>
+#include <stdio.h>
+#include <trace.h>
+#include <kernel/pseudo_ta.h>
+#include <mm/tee_pager.h>
+#include <mm/tee_mm.h>
+#include <string.h>
+#include <string_ext.h>
+#include <malloc.h>
+
+#define TA_NAME "stats.ta"
+
+#define STATS_UUID \
+ { 0xd96a5b40, 0xe2c7, 0xb1af, \
+ { 0x87, 0x94, 0x10, 0x02, 0xa5, 0xd5, 0xc6, 0x1b } }
+
+#define STATS_CMD_PAGER_STATS 0
+#define STATS_CMD_ALLOC_STATS 1
+
+#define STATS_NB_POOLS 3
+
+static TEE_Result get_alloc_stats(uint32_t type, TEE_Param p[TEE_NUM_PARAMS])
+{
+ struct malloc_stats *stats;
+ uint32_t size_to_retrieve;
+ uint32_t pool_id;
+ uint32_t i;
+
+ /*
+ * p[0].value.a = pool id (from 0 to n)
+ * - 0 means all the pools to be retrieved
+ * - 1..n means pool id
+ * p[0].value.b = 0 if no reset of the stats
+ * p[1].memref.buffer = output buffer to struct malloc_stats
+ */
+ if (TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
+ TEE_PARAM_TYPE_MEMREF_OUTPUT,
+ TEE_PARAM_TYPE_NONE,
+ TEE_PARAM_TYPE_NONE) != type) {
+ return TEE_ERROR_BAD_PARAMETERS;
+ }
+
+ pool_id = p[0].value.a;
+ if (pool_id > STATS_NB_POOLS)
+ return TEE_ERROR_BAD_PARAMETERS;
+
+ size_to_retrieve = sizeof(struct malloc_stats);
+ if (!pool_id)
+ size_to_retrieve *= STATS_NB_POOLS;
+
+ if (p[1].memref.size < size_to_retrieve) {
+ p[1].memref.size = size_to_retrieve;
+ return TEE_ERROR_SHORT_BUFFER;
+ }
+ p[1].memref.size = size_to_retrieve;
+ stats = p[1].memref.buffer;
+
+ for (i = 1; i <= STATS_NB_POOLS; i++) {
+ if ((pool_id) && (i != pool_id))
+ continue;
+
+ switch (i) {
+ case 1:
+ malloc_get_stats(stats);
+ strlcpy(stats->desc, "Heap", sizeof(stats->desc));
+ if (p[0].value.b)
+ malloc_reset_stats();
+ break;
+
+ case 2:
+ EMSG("public DDR not managed by secure side anymore");
+ break;
+
+ case 3:
+ tee_mm_get_pool_stats(&tee_mm_sec_ddr, stats,
+ !!p[0].value.b);
+ strlcpy(stats->desc, "Secure DDR", sizeof(stats->desc));
+ break;
+
+ default:
+ EMSG("Wrong pool id");
+ break;
+ }
+
+ stats++;
+ }
+
+ return TEE_SUCCESS;
+}
+
+static TEE_Result get_pager_stats(uint32_t type, TEE_Param p[TEE_NUM_PARAMS])
+{
+ struct tee_pager_stats stats;
+
+ if (TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT,
+ TEE_PARAM_TYPE_VALUE_OUTPUT,
+ TEE_PARAM_TYPE_VALUE_OUTPUT,
+ TEE_PARAM_TYPE_NONE) != type) {
+ EMSG("expect 3 output values as argument");
+ return TEE_ERROR_BAD_PARAMETERS;
+ }
+
+ tee_pager_get_stats(&stats);
+ p[0].value.a = stats.npages;
+ p[0].value.b = stats.npages_all;
+ p[1].value.a = stats.ro_hits;
+ p[1].value.b = stats.rw_hits;
+ p[2].value.a = stats.hidden_hits;
+ p[2].value.b = stats.zi_released;
+
+ return TEE_SUCCESS;
+}
+
+/*
+ * Trusted Application Entry Points
+ */
+
+static TEE_Result invoke_command(void *psess __unused,
+ uint32_t cmd, uint32_t ptypes,
+ TEE_Param params[TEE_NUM_PARAMS])
+{
+ switch (cmd) {
+ case STATS_CMD_PAGER_STATS:
+ return get_pager_stats(ptypes, params);
+ case STATS_CMD_ALLOC_STATS:
+ return get_alloc_stats(ptypes, params);
+ default:
+ break;
+ }
+ return TEE_ERROR_BAD_PARAMETERS;
+}
+
+pseudo_ta_register(.uuid = STATS_UUID, .name = TA_NAME,
+ .flags = PTA_DEFAULT_FLAGS,
+ .invoke_command_entry_point = invoke_command);