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