1 /*
2 * Copyright 2018, NXP
3 * All rights reserved.
4 *
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "srtm_message_pool.h"
10 #include "srtm_heap.h"
11 #include "srtm_list.h"
12 #include "fsl_common.h"
13
14 /*******************************************************************************
15 * Definitions
16 ******************************************************************************/
17 /* Simple algorithm:
18 * Here we suppose most SRTM messages data are small.
19 * By default we set each message buffer to 96 (0x60) bytes (including struct _srtm_message
20 * which occupies 52 bytes). So we have 44 bytes for the SRTM message data (10bytes header +
21 * 34 bytes payload which is sufficient for all current SRTM category).
22 */
23 /* Total buffer size for messages in the pool. */
24 #ifndef SRTM_MESSAGE_POOL_SIZE
25 #define SRTM_MESSAGE_POOL_SIZE (0x1000)
26 #endif
27
28 /* Each message buffer size */
29 #ifndef SRTM_MESSAGE_BUF_SIZE
30 #define SRTM_MESSAGE_BUF_SIZE (0x60)
31 #endif
32
33 /*******************************************************************************
34 * Prototypes
35 ******************************************************************************/
36 /* Define a structure to hold SRTM_MESSAGE_BUF_SIZE buffer. */
37 typedef struct
38 {
39 srtm_list_t node;
40 uint8_t buf[SRTM_MESSAGE_BUF_SIZE - sizeof(srtm_list_t)];
41 } srtm_message_buf_t;
42
43 /*******************************************************************************
44 * Variables
45 ******************************************************************************/
46 static srtm_message_buf_t srtmMsgs[SRTM_MESSAGE_POOL_SIZE / sizeof(srtm_message_buf_t)];
47 static srtm_list_t srtmMsgList;
48 #ifdef SRTM_DEBUG_MESSAGE_FUNC
49 /* Used for probe current and minimum free message buffer count in debugger. */
50 static uint32_t freeMsgCount;
51 static uint32_t minFreeMsgCount;
52 #endif
53
54 /*******************************************************************************
55 * Code
56 ******************************************************************************/
SRTM_MessagePool_Alloc(uint32_t size)57 void *SRTM_MessagePool_Alloc(uint32_t size)
58 {
59 uint32_t i;
60 void *buf;
61 uint32_t primask;
62
63 if (srtmMsgList.next == NULL)
64 {
65 primask = DisableGlobalIRQ();
66 if (srtmMsgList.next == NULL)
67 {
68 /* Message list not initialized, initialize now */
69 SRTM_List_Init(&srtmMsgList);
70 for (i = 0; i < sizeof(srtmMsgs) / sizeof(srtm_message_buf_t); i++)
71 {
72 SRTM_List_AddTail(&srtmMsgList, &srtmMsgs[i].node);
73 }
74 #ifdef SRTM_DEBUG_MESSAGE_FUNC
75 freeMsgCount = sizeof(srtmMsgs) / sizeof(srtm_message_buf_t);
76 minFreeMsgCount = freeMsgCount;
77 #endif
78 }
79 EnableGlobalIRQ(primask);
80 }
81
82 if (size > sizeof(srtm_message_buf_t))
83 {
84 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_INFO,
85 "Message size larger than SRTM_MESSAGE_BUF_SIZE %d, allocated in heap.\r\n",
86 SRTM_MESSAGE_BUF_SIZE);
87 buf = SRTM_Heap_Malloc(size);
88 }
89 else
90 {
91 primask = DisableGlobalIRQ();
92 if (SRTM_List_IsEmpty(&srtmMsgList))
93 {
94 EnableGlobalIRQ(primask);
95 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_WARN, "Message pool (size %d) used up, allocated in heap.\r\n",
96 SRTM_MESSAGE_POOL_SIZE);
97 buf = SRTM_Heap_Malloc(size);
98 }
99 else
100 {
101 buf = (void *)srtmMsgList.next;
102 SRTM_List_Remove(srtmMsgList.next);
103 #ifdef SRTM_DEBUG_MESSAGE_FUNC
104 freeMsgCount--;
105 if (freeMsgCount < minFreeMsgCount)
106 {
107 minFreeMsgCount = freeMsgCount;
108 }
109 #endif
110 EnableGlobalIRQ(primask);
111 }
112 }
113
114 return buf;
115 }
116
SRTM_MessagePool_Free(void * buf)117 void SRTM_MessagePool_Free(void *buf)
118 {
119 srtm_message_buf_t *msgBuf;
120 uint32_t primask;
121
122 if ((buf >= (void *)&srtmMsgs[0]) && (buf < (void *)(&srtmMsgs[sizeof(srtmMsgs) / sizeof(srtm_message_buf_t)])))
123 {
124 /* buffer locates in message pool */
125 assert(((uint32_t)(uint8_t *)(buf) - (uint32_t)&srtmMsgs[0]) % sizeof(srtm_message_buf_t) == 0U);
126 msgBuf = (srtm_message_buf_t *)buf;
127 primask = DisableGlobalIRQ();
128 SRTM_List_AddTail(&srtmMsgList, &msgBuf->node);
129 #ifdef SRTM_DEBUG_MESSAGE_FUNC
130 freeMsgCount++;
131 #endif
132 EnableGlobalIRQ(primask);
133 }
134 else
135 {
136 SRTM_Heap_Free(buf);
137 }
138 }
139