1 /*
2 * Copyright (c) 2022, Cypress Semiconductor Corporation. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include <stdint.h>
9 #include "ffm/backend.h"
10 #include "stack_watermark.h"
11 #include "lists.h"
12 #include "load/spm_load_api.h"
13 #include "spm.h"
14 #include "tfm_spm_log.h"
15
16 /* Always output, regardless of log level.
17 * If you don't want output, don't build this code
18 */
19 #define SPMLOG(x) tfm_hal_output_spm_log((x), sizeof(x))
20 #define SPMLOG_VAL(x, y) spm_log_msgval((x), sizeof(x), y)
21
22 #define STACK_WATERMARK_VAL 0xdeadbeef
23
watermark_stack(struct partition_t * p_pt)24 void watermark_stack(struct partition_t *p_pt)
25 {
26 const struct partition_load_info_t *p_pldi = p_pt->p_ldinf;
27
28 for (int i = 0; i < p_pldi->stack_size / 4; i++) {
29 *((uint32_t *)LOAD_ALLOCED_STACK_ADDR(p_pldi) + i) = STACK_WATERMARK_VAL;
30 }
31 }
32
33 /* Returns the number of bytes of stack that have been used by the specified partition */
used_stack(struct partition_t * p_pt)34 static uint32_t used_stack(struct partition_t *p_pt)
35 {
36 const struct partition_load_info_t *p_pldi = p_pt->p_ldinf;
37 uint32_t unused_words = 0;
38
39 for (const uint32_t *p = (uint32_t *)LOAD_ALLOCED_STACK_ADDR(p_pldi);
40 p < (uint32_t *)(LOAD_ALLOCED_STACK_ADDR(p_pldi) + p_pldi->stack_size);
41 p++) {
42 if (*p != STACK_WATERMARK_VAL) {
43 break;
44 }
45 unused_words++;
46 }
47
48 return p_pldi->stack_size - (unused_words * 4);
49 }
50
dump_used_stacks(void)51 void dump_used_stacks(void)
52 {
53 struct partition_t *p_pt;
54
55 SPMLOG("Used stack sizes report\r\n");
56 UNI_LIST_FOREACH(p_pt, PARTITION_LIST_ADDR, next) {
57 SPMLOG_VAL(" Partition id: ", p_pt->p_ldinf->pid);
58 SPMLOG_VAL(" Stack bytes: ", p_pt->p_ldinf->stack_size);
59 SPMLOG_VAL(" Stack bytes used: ", used_stack(p_pt));
60 }
61 }
62