SPM: Refine list operations
List operations is necessary for FFM common logic. Move the header
into 'ffm' folder, and covert inline funtions into MACROs, as list
operations are fast and simple enough.
The main usage now for the lists is a ring based on the bidirectional
list structure. Other list usage can be added into this file when
necessary.
Change-Id: I45c5eab864f5c4e261b39c89cd42325bb98fa17c
Signed-off-by: Ken Liu <Ken.Liu@arm.com>
diff --git a/docs/design_documents/tfm_partition_and_service_design_document.rst b/docs/design_documents/tfm_partition_and_service_design_document.rst
index 33edbe2..b23ae01 100644
--- a/docs/design_documents/tfm_partition_and_service_design_document.rst
+++ b/docs/design_documents/tfm_partition_and_service_design_document.rst
@@ -118,9 +118,9 @@
struct tfm_spm_service_t {
const struct tfm_spm_service_db_t *service_db;
struct spm_partition_desc_t *partition;
- struct tfm_list_node_t handle_list;
+ struct bi_list_node_t handle_list;
struct tfm_msg_queue_t msg_queue;
- struct tfm_list_node_t list;
+ struct bi_list_node_t list;
};
These members are necessary for a service and the following bullets explain the
diff --git a/secure_fw/spm/cmsis_psa/spm_ipc.c b/secure_fw/spm/cmsis_psa/spm_ipc.c
index dd4477b..983d5d4 100644
--- a/secure_fw/spm/cmsis_psa/spm_ipc.c
+++ b/secure_fw/spm/cmsis_psa/spm_ipc.c
@@ -24,7 +24,7 @@
#include "tfm_core_utils.h"
#include "tfm_rpc.h"
#include "tfm_core_trustzone.h"
-#include "tfm_list.h"
+#include "ffm/lists.h"
#include "tfm_pools.h"
#include "region.h"
#include "region_defs.h"
@@ -152,7 +152,7 @@
p_handle->client_id = client_id;
/* Add handle node to list for next psa functions */
- tfm_list_add_tail(&service->handle_list, &p_handle->list);
+ BI_LIST_INSERT_BEFORE(&service->handle_list, &p_handle->list);
return p_handle;
}
@@ -185,7 +185,7 @@
conn_handle->internal_msg.magic = 0;
/* Remove node from handle list */
- tfm_list_del_node(&conn_handle->list);
+ BI_LIST_REMOVE_NODE(&conn_handle->list);
/* Back handle buffer to pool */
tfm_pool_free(conn_handle);
@@ -232,14 +232,14 @@
struct tfm_msg_body_t *tfm_spm_get_msg_by_signal(struct partition_t *partition,
psa_signal_t signal)
{
- struct tfm_list_node_t *node, *head;
+ struct bi_list_node_t *node, *head;
struct tfm_msg_body_t *tmp_msg, *msg = NULL;
TFM_CORE_ASSERT(partition);
head = &partition->msg_list;
- if (tfm_list_is_empty(head)) {
+ if (BI_LIST_IS_EMPTY(head)) {
return NULL;
}
@@ -247,13 +247,13 @@
* There may be multiple messages for this RoT Service signal, do not clear
* partition mask until no remaining message. Search may be optimized.
*/
- TFM_LIST_FOR_EACH(node, head) {
+ BI_LIST_FOR_EACH(node, head) {
tmp_msg = TFM_GET_CONTAINER_PTR(node, struct tfm_msg_body_t, msg_node);
if (tmp_msg->service->service_db->signal == signal && msg) {
return msg;
} else if (tmp_msg->service->service_db->signal == signal) {
msg = tmp_msg;
- tfm_list_del_node(node);
+ BI_LIST_REMOVE_NODE(node);
}
}
@@ -559,7 +559,7 @@
TFM_CORE_ASSERT(msg);
/* Add message to partition message list tail */
- tfm_list_add_tail(&partition->msg_list, &msg->msg_node);
+ BI_LIST_INSERT_BEFORE(&partition->msg_list, &msg->msg_node);
/* Messages put. Update signals */
partition->signals_asserted |= service->service_db->signal;
@@ -692,7 +692,7 @@
}
tfm_event_init(&partition->event);
- tfm_list_init(&partition->msg_list);
+ BI_LIST_INIT_NODE(&partition->msg_list);
pth = &partition->sp_thread;
if (!pth) {
@@ -730,7 +730,7 @@
service[i].partition = partition;
partition->signals_allowed |= service[i].service_db->signal;
- tfm_list_init(&service[i].handle_list);
+ BI_LIST_INIT_NODE(&service[i].handle_list);
}
/*
diff --git a/secure_fw/spm/cmsis_psa/spm_ipc.h b/secure_fw/spm/cmsis_psa/spm_ipc.h
index d8ffe48..303c543 100644
--- a/secure_fw/spm/cmsis_psa/spm_ipc.h
+++ b/secure_fw/spm/cmsis_psa/spm_ipc.h
@@ -11,7 +11,7 @@
#include <stdint.h>
#include "spm_partition_defs.h"
#include "tfm_arch.h"
-#include "tfm_list.h"
+#include "ffm/lists.h"
#include "tfm_wait.h"
#include "tfm_secure_api.h"
#include "tfm_thread.h"
@@ -74,7 +74,7 @@
* client calls in multi-core topology
*/
#endif
- struct tfm_list_node_t msg_node; /* For list operators */
+ struct bi_list_node_t msg_node; /* For list operators */
};
/**
@@ -107,7 +107,7 @@
void *p_metadata;
struct tfm_core_thread_t sp_thread;
struct tfm_event_t event;
- struct tfm_list_node_t msg_list;
+ struct bi_list_node_t msg_list;
uint32_t signals_allowed;
uint32_t signals_waiting;
uint32_t signals_asserted;
@@ -140,8 +140,8 @@
* Point to secure partition
* data
*/
- struct tfm_list_node_t handle_list; /* Service handle list */
- struct tfm_list_node_t list; /* For list operation */
+ struct bi_list_node_t handle_list; /* Service handle list */
+ struct bi_list_node_t list; /* For list operation */
};
/* RoT connection handle list */
@@ -162,7 +162,7 @@
*/
struct tfm_msg_body_t internal_msg; /* Internal message for message queue */
struct tfm_spm_service_t *service; /* RoT service pointer */
- struct tfm_list_node_t list; /* list node */
+ struct bi_list_node_t list; /* list node */
};
enum tfm_memory_access_e {
diff --git a/secure_fw/spm/cmsis_psa/tfm_list.h b/secure_fw/spm/cmsis_psa/tfm_list.h
deleted file mode 100644
index f643b38..0000000
--- a/secure_fw/spm/cmsis_psa/tfm_list.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-#ifndef __TFM_LIST_H__
-#define __TFM_LIST_H__
-
-#include "cmsis_compiler.h"
-
-/* List structure */
-struct tfm_list_node_t {
- struct tfm_list_node_t *prev;
- struct tfm_list_node_t *next;
-};
-
-/**
- * \brief Initialize list head.
- *
- * \param[in] head List head need to be initialized.
- */
-__STATIC_INLINE void tfm_list_init(struct tfm_list_node_t *head)
-{
- head->next = head;
- head->prev = head;
-}
-
-/**
- * \brief Add one node to list tail.
- *
- * \param[in] head List head initialized by \ref tfm_list_init.
- * \param[in] node List node want to be added.
- */
-__STATIC_INLINE void
-tfm_list_add_tail(struct tfm_list_node_t *head, struct tfm_list_node_t *node)
-{
- head->prev->next = node;
- node->prev = head->prev;
- head->prev = node;
- node->next = head;
-}
-
-/**
- * \brief Check if a list is empty.
- *
- * \param[in] head List head initialized by \ref tfm_list_init.
- *
- * \returns returns 1 for empty, or 0 for not.
- */
-__STATIC_INLINE int32_t tfm_list_is_empty(struct tfm_list_node_t *head)
-{
- return (head->next == head);
-}
-
-/**
- * \brief Insert one node to list head.
- *
- * \param[in] head List head initialized by \ref tfm_list_init.
- * \param[in] node List node want to be inserted.
- */
-__STATIC_INLINE void
-tfm_list_insert_first(struct tfm_list_node_t *head,
- struct tfm_list_node_t *node)
-{
- node->next = head->next;
- node->prev = head;
- head->next->prev = node;
- head->next = node;
-}
-
-/**
- * \brief Retrieve the fist node from list.
- *
- * \param[in] head List head initialized by \ref tfm_list_init.
- *
- * \returns Returns the pointer to first list node.
- */
-__STATIC_INLINE
-struct tfm_list_node_t *tfm_list_first_node(struct tfm_list_node_t *head)
-{
- return head->next;
-}
-
-/**
- * \brief Delete one node from list.
- *
- * \param[in] node List node want to be deleted.
- */
-__STATIC_INLINE void tfm_list_del_node(struct tfm_list_node_t *node)
-{
- node->prev->next = node->next;
- node->next->prev = node->prev;
-}
-
-/* Go through each node of a list */
-#define TFM_LIST_FOR_EACH(node, head) \
- for (node = (head)->next; node != head; node = node->next)
-
-#endif
diff --git a/secure_fw/spm/cmsis_psa/tfm_pools.c b/secure_fw/spm/cmsis_psa/tfm_pools.c
index 7c02ac5..8045f08 100644
--- a/secure_fw/spm/cmsis_psa/tfm_pools.c
+++ b/secure_fw/spm/cmsis_psa/tfm_pools.c
@@ -14,7 +14,7 @@
#include "internal_errors.h"
#include "cmsis_compiler.h"
#include "utilities.h"
-#include "tfm_list.h"
+#include "ffm/lists.h"
#include "tfm_pools.h"
#include "tfm_memory_utils.h"
#include "tfm_core_utils.h"
@@ -39,12 +39,12 @@
spm_memset(pool, 0, poolsz);
/* Chain pool chunks */
- tfm_list_init(&pool->chunks_list);
+ BI_LIST_INIT_NODE(&pool->chunks_list);
pchunk = (struct tfm_pool_chunk_t *)pool->chunks;
for (i = 0; i < num; i++) {
pchunk->pool = pool;
- tfm_list_add_tail(&pool->chunks_list, &pchunk->list);
+ BI_LIST_INSERT_BEFORE(&pool->chunks_list, &pchunk->list);
pchunk = (struct tfm_pool_chunk_t *)&pchunk->data[chunksz];
}
@@ -57,22 +57,22 @@
void *tfm_pool_alloc(struct tfm_pool_instance_t *pool)
{
- struct tfm_list_node_t *node;
+ struct bi_list_node_t *node;
struct tfm_pool_chunk_t *pchunk;
if (!pool) {
return NULL;
}
- if (tfm_list_is_empty(&pool->chunks_list)) {
+ if (BI_LIST_IS_EMPTY(&pool->chunks_list)) {
return NULL;
}
- node = tfm_list_first_node(&pool->chunks_list);
+ node = BI_LIST_NEXT_NODE(&pool->chunks_list);
pchunk = TFM_GET_CONTAINER_PTR(node, struct tfm_pool_chunk_t, list);
/* Remove node from list node, it will be added when pool free */
- tfm_list_del_node(node);
+ BI_LIST_REMOVE_NODE(node);
return &pchunk->data;
}
@@ -84,7 +84,7 @@
pchunk = TFM_GET_CONTAINER_PTR(ptr, struct tfm_pool_chunk_t, data);
pool = (struct tfm_pool_instance_t *)pchunk->pool;
- tfm_list_add_tail(&pool->chunks_list, &pchunk->list);
+ BI_LIST_INSERT_BEFORE(&pool->chunks_list, &pchunk->list);
}
bool is_valid_chunk_data_in_pool(struct tfm_pool_instance_t *pool,
diff --git a/secure_fw/spm/cmsis_psa/tfm_pools.h b/secure_fw/spm/cmsis_psa/tfm_pools.h
index b1f39d9..a71aa8c 100644
--- a/secure_fw/spm/cmsis_psa/tfm_pools.h
+++ b/secure_fw/spm/cmsis_psa/tfm_pools.h
@@ -9,7 +9,7 @@
#include <stdbool.h>
-#include "tfm_list.h"
+#include "ffm/lists.h"
#ifdef __cplusplus
extern "C" {
@@ -25,7 +25,7 @@
* [ Pool Instance ] + N * [ Pool Chunks ]
*/
struct tfm_pool_chunk_t {
- struct tfm_list_node_t list; /* Chunk list */
+ struct bi_list_node_t list; /* Chunk list */
void *pool; /* Point to the parent pool */
uint8_t data[0]; /* Data indicator */
};
@@ -35,14 +35,14 @@
* required for standards compliant C
*/
struct tfm_pool_chunk_s_t {
- struct tfm_list_node_t list; /* Chunk list */
+ struct bi_list_node_t list; /* Chunk list */
void *pool; /* Point to the parent pool */
};
struct tfm_pool_instance_t {
size_t chunksz; /* Chunks size of pool member */
size_t chunk_count; /* A number of chunks in the pool */
- struct tfm_list_node_t chunks_list; /* Chunk list head in pool */
+ struct bi_list_node_t chunks_list; /* Chunk list head in pool */
struct tfm_pool_chunk_s_t chunks[0]; /* Data indicator */
};
diff --git a/secure_fw/spm/include/ffm/lists.h b/secure_fw/spm/include/ffm/lists.h
new file mode 100644
index 0000000..41c540a
--- /dev/null
+++ b/secure_fw/spm/include/ffm/lists.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#ifndef __LISTS_H__
+#define __LISTS_H__
+
+/* Bi-directional list structure */
+struct bi_list_node_t {
+ struct bi_list_node_t *prev;
+ struct bi_list_node_t *next;
+};
+
+/* Init an empty node. */
+#define BI_LIST_INIT_NODE(node) do { \
+ (node)->next = node; \
+ (node)->prev = node; \
+} while(0)
+
+/* Insert a new node after (next) current. */
+#define BI_LIST_INSERT_AFTER(curr, node) do { \
+ (node)->next = (curr)->next; \
+ (node)->prev = curr; \
+ (curr)->next->prev = node; \
+ (curr)->next = node; \
+} while(0)
+
+/* Add one node into list as the tail (prev) of head. */
+#define BI_LIST_INSERT_BEFORE(curr, node) do { \
+ (curr)->prev->next = node; \
+ (node)->prev = (curr)->prev; \
+ (curr)->prev = node; \
+ (node)->next = curr; \
+} while(0)
+
+/* Remove one node from the list. */
+#define BI_LIST_REMOVE_NODE(node) do { \
+ (node)->prev->next = (node)->next; \
+ (node)->next->prev = (node)->prev; \
+} while(0)
+
+/* Is the head empty? */
+#define BI_LIST_IS_EMPTY(head) ((head)->next == (head))
+
+/* The node's next node */
+#define BI_LIST_NEXT_NODE(node) ((node)->next)
+
+/* Go through each node of a list */
+#define BI_LIST_FOR_EACH(node, head) \
+ for (node = (head)->next; node != head; node = (node)->next)
+
+#endif /* __LISTS_H__ */