TF-M Reference Manual  1.2.0
TrustedFirmware-M
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
tfm_pools.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 #include <inttypes.h>
8 #include <stdbool.h>
9 #include <stdlib.h>
10 #include "tfm_thread.h"
11 #include "tfm_wait.h"
12 #include "psa/client.h"
13 #include "psa/service.h"
14 #include "tfm_internal_defines.h"
15 #include "cmsis_compiler.h"
16 #include "utilities.h"
17 #include "tfm_list.h"
18 #include "tfm_pools.h"
19 #include "tfm_memory_utils.h"
20 #include "tfm_core_utils.h"
21 
22 int32_t tfm_pool_init(struct tfm_pool_instance_t *pool, size_t poolsz,
23  size_t chunksz, size_t num)
24 {
25  struct tfm_pool_chunk_t *pchunk;
26  size_t i;
27 
28  if (!pool || num == 0) {
30  }
31 
32  /* Ensure buffer is large enough */
33  if (poolsz != ((chunksz + sizeof(struct tfm_pool_chunk_t)) * num +
34  sizeof(struct tfm_pool_instance_t))) {
36  }
37 
38  /* Buffer should be BSS cleared but clear it again */
39  spm_memset(pool, 0, poolsz);
40 
41  /* Chain pool chunks */
42  tfm_list_init(&pool->chunks_list);
43 
44  pchunk = (struct tfm_pool_chunk_t *)pool->chunks;
45  for (i = 0; i < num; i++) {
46  pchunk->pool = pool;
47  tfm_list_add_tail(&pool->chunks_list, &pchunk->list);
48  pchunk = (struct tfm_pool_chunk_t *)&pchunk->data[chunksz];
49  }
50 
51  /* Prepare instance and insert to pool list */
52  pool->chunksz = chunksz;
53  pool->chunk_count = num;
54 
55  return IPC_SUCCESS;
56 }
57 
59 {
60  struct tfm_list_node_t *node;
61  struct tfm_pool_chunk_t *pchunk;
62 
63  if (!pool) {
64  return NULL;
65  }
66 
67  if (tfm_list_is_empty(&pool->chunks_list)) {
68  return NULL;
69  }
70 
71  node = tfm_list_first_node(&pool->chunks_list);
72  pchunk = TFM_GET_CONTAINER_PTR(node, struct tfm_pool_chunk_t, list);
73 
74  /* Remove node from list node, it will be added when pool free */
75  tfm_list_del_node(node);
76 
77  return &pchunk->data;
78 }
79 
80 void tfm_pool_free(void *ptr)
81 {
82  struct tfm_pool_chunk_t *pchunk;
83  struct tfm_pool_instance_t *pool;
84 
85  pchunk = TFM_GET_CONTAINER_PTR(ptr, struct tfm_pool_chunk_t, data);
86  pool = (struct tfm_pool_instance_t *)pchunk->pool;
87  tfm_list_add_tail(&pool->chunks_list, &pchunk->list);
88 }
89 
91  uint8_t *data)
92 {
93  const uintptr_t chunks_start = (uintptr_t)(pool->chunks);
94  const size_t chunks_size = pool->chunksz + sizeof(struct tfm_pool_chunk_t);
95  const size_t chunk_count = pool->chunk_count;
96  const uintptr_t chunks_end = chunks_start + chunks_size * chunk_count;
97  uintptr_t pool_chunk_address = 0;
98 
99  /* Check that the message was allocated from the pool. */
100  if ((uintptr_t)data < chunks_start || (uintptr_t)data >= chunks_end) {
101  return false;
102  }
103 
104  pool_chunk_address =
105  (uint32_t)TFM_GET_CONTAINER_PTR(data, struct tfm_pool_chunk_t, data);
106 
107  /* Make sure that the chunk containing the message is aligned on */
108  /* chunk boundary in the pool. */
109  if ((pool_chunk_address - chunks_start) % chunks_size != 0) {
110  return false;
111  }
112  return true;
113 }
__STATIC_INLINE void tfm_list_del_node(struct tfm_list_node_t *node)
Delete one node from list.
Definition: tfm_list.h:88
void tfm_pool_free(void *ptr)
Free the allocated memory.
Definition: tfm_pools.c:80
struct tfm_list_node_t chunks_list
Definition: tfm_pools.h:43
void * tfm_pool_alloc(struct tfm_pool_instance_t *pool)
Allocate a memory from pool.
Definition: tfm_pools.c:58
#define IPC_ERROR_BAD_PARAMETERS
__STATIC_INLINE struct tfm_list_node_t * tfm_list_first_node(struct tfm_list_node_t *head)
Retrieve the fist node from list.
Definition: tfm_list.h:78
void * spm_memset(void *s, int c, size_t n)
Memory set function for TF-M core.
uint8_t data[0]
Definition: tfm_pools.h:28
int32_t tfm_pool_init(struct tfm_pool_instance_t *pool, size_t poolsz, size_t chunksz, size_t num)
Register a memory pool.
Definition: tfm_pools.c:22
#define TFM_GET_CONTAINER_PTR(ptr, type, member)
Definition: utilities.h:33
struct tfm_list_node_t list
Definition: tfm_pools.h:26
#define IPC_SUCCESS
__STATIC_INLINE void tfm_list_init(struct tfm_list_node_t *head)
Initialize list head.
Definition: tfm_list.h:21
struct tfm_pool_chunk_s_t chunks[0]
Definition: tfm_pools.h:44
__STATIC_INLINE int32_t tfm_list_is_empty(struct tfm_list_node_t *head)
Check if a list is empty.
Definition: tfm_list.h:49
__STATIC_INLINE void tfm_list_add_tail(struct tfm_list_node_t *head, struct tfm_list_node_t *node)
Add one node to list tail.
Definition: tfm_list.h:34
bool is_valid_chunk_data_in_pool(struct tfm_pool_instance_t *pool, uint8_t *data)
Checks whether a pointer points to a chunk data in the pool.
Definition: tfm_pools.c:90