xref: /freebsd/sys/contrib/ncsw/inc/etc/mem_ext.h (revision 193d9e768ba63fcfb187cfd17f461f7d41345048)
1 /* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *     * Redistributions of source code must retain the above copyright
7  *       notice, this list of conditions and the following disclaimer.
8  *     * Redistributions in binary form must reproduce the above copyright
9  *       notice, this list of conditions and the following disclaimer in the
10  *       documentation and/or other materials provided with the distribution.
11  *     * Neither the name of Freescale Semiconductor nor the
12  *       names of its contributors may be used to endorse or promote products
13  *       derived from this software without specific prior written permission.
14  *
15  *
16  * ALTERNATIVELY, this software may be distributed under the terms of the
17  * GNU General Public License ("GPL") as published by the Free Software
18  * Foundation, either version 2 of that License or (at your option) any
19  * later version.
20  *
21  * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24  * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /**************************************************************************//**
34 
35  @File          mem_ext.h
36 
37  @Description   External prototypes for the memory manager object
38 *//***************************************************************************/
39 
40 #ifndef __MEM_EXT_H
41 #define __MEM_EXT_H
42 
43 #include "std_ext.h"
44 #include "part_ext.h"
45 
46 
47 /**************************************************************************//**
48  @Group         etc_id   Utility Library Application Programming Interface
49 
50  @Description   External routines.
51 
52  @{
53 *//***************************************************************************/
54 
55 /**************************************************************************//**
56  @Group         mem_id   Slab Memory Manager
57 
58  @Description   Slab Memory Manager module functions, definitions and enums.
59 
60  @{
61 *//***************************************************************************/
62 
63 /* Each block is of the following structure:
64  *
65  *
66  *  +-----------+----------+---------------------------+-----------+-----------+
67  *  | Alignment |  Prefix  | Data                      | Postfix   | Alignment |
68  *  |  field    |   field  |  field                    |   field   | Padding   |
69  *  |           |          |                           |           |           |
70  *  +-----------+----------+---------------------------+-----------+-----------+
71  *  and at the beginning of all bytes, an additional optional padding might reside
72  *  to ensure that the first blocks data field is aligned as requested.
73  */
74 
75 
76 #define MEM_MAX_NAME_LENGTH     8
77 
78 /**************************************************************************//*
79  @Description   Memory Segment structure
80 *//***************************************************************************/
81 
82 typedef struct
83 {
84     char        name[MEM_MAX_NAME_LENGTH];
85                                     /* The segment's name */
86     uint8_t     **p_Bases;          /* Base addresses of the segments */
87     uint8_t     **p_BlocksStack;    /* Array of pointers to blocks */
88     t_Handle    h_Spinlock;
89     uint16_t    dataSize;           /* Size of each data block */
90     uint16_t    prefixSize;         /* How many bytes to reserve before the data */
91     uint16_t    postfixSize;        /* How many bytes to reserve after the data */
92     uint16_t    alignment;          /* Requested alignment for the data field */
93     int         allocOwner;         /* Memory allocation owner */
94     uint32_t    getFailures;        /* Number of times get failed */
95     uint32_t    num;                /* Number of blocks in segment */
96     uint32_t    current;            /* Current block */
97     bool        consecutiveMem;     /* Allocate consecutive data blocks memory */
98 #ifdef DEBUG_MEM_LEAKS
99     void        *p_MemDbg;          /* MEM debug database (MEM leaks detection) */
100     uint32_t    blockOffset;
101     uint32_t    blockSize;
102 #endif /* DEBUG_MEM_LEAKS */
103 } t_MemorySegment;
104 
105 
106 
107 /**************************************************************************//**
108  @Function      MEM_Init
109 
110  @Description   Create a new memory segment.
111 
112  @Param[in]     name        - Name of memory partition.
113  @Param[in]     p_Handle    - Handle to new segment is returned through here.
114  @Param[in]     num         - Number of blocks in new segment.
115  @Param[in]     dataSize    - Size of blocks in segment.
116  @Param[in]     prefixSize  - How many bytes to allocate before the data.
117  @Param[in]     postfixSize - How many bytes to allocate after the data.
118  @Param[in]     alignment   - Requested alignment for data field (in bytes).
119 
120  @Return        E_OK - success, E_NO_MEMORY - out of memory.
121 *//***************************************************************************/
122 t_Error MEM_Init(char     name[],
123                  t_Handle *p_Handle,
124                  uint32_t num,
125                  uint16_t dataSize,
126                  uint16_t prefixSize,
127                  uint16_t postfixSize,
128                  uint16_t alignment);
129 
130 /**************************************************************************//**
131  @Function      MEM_InitSmart
132 
133  @Description   Create a new memory segment.
134 
135  @Param[in]     name            - Name of memory partition.
136  @Param[in]     p_Handle        - Handle to new segment is returned through here.
137  @Param[in]     num             - Number of blocks in new segment.
138  @Param[in]     dataSize        - Size of blocks in segment.
139  @Param[in]     prefixSize      - How many bytes to allocate before the data.
140  @Param[in]     postfixSize     - How many bytes to allocate after the data.
141  @Param[in]     alignment       - Requested alignment for data field (in bytes).
142  @Param[in]     memPartitionId  - Memory partition ID for allocation.
143  @Param[in]     consecutiveMem  - Whether to allocate the memory blocks
144                                   continuously or not.
145 
146  @Return        E_OK - success, E_NO_MEMORY - out of memory.
147 *//***************************************************************************/
148 t_Error MEM_InitSmart(char      name[],
149                       t_Handle  *p_Handle,
150                       uint32_t  num,
151                       uint16_t  dataSize,
152                       uint16_t  prefixSize,
153                       uint16_t  postfixSize,
154                       uint16_t  alignment,
155                       uint8_t   memPartitionId,
156                       bool      consecutiveMem);
157 
158 /**************************************************************************//**
159  @Function      MEM_InitByAddress
160 
161  @Description   Create a new memory segment with a specified base address.
162 
163  @Param[in]     name        - Name of memory partition.
164  @Param[in]     p_Handle    - Handle to new segment is returned through here.
165  @Param[in]     num         - Number of blocks in new segment.
166  @Param[in]     dataSize    - Size of blocks in segment.
167  @Param[in]     prefixSize  - How many bytes to allocate before the data.
168  @Param[in]     postfixSize - How many bytes to allocate after the data.
169  @Param[in]     alignment   - Requested alignment for data field (in bytes).
170  @Param[in]     address     - The required base address.
171 
172  @Return        E_OK - success, E_NO_MEMORY - out of memory.
173  *//***************************************************************************/
174 t_Error MEM_InitByAddress(char        name[],
175                           t_Handle    *p_Handle,
176                           uint32_t    num,
177                           uint16_t    dataSize,
178                           uint16_t    prefixSize,
179                           uint16_t    postfixSize,
180                           uint16_t    alignment,
181                           uint8_t     *address);
182 
183 /**************************************************************************//**
184  @Function      MEM_Free
185 
186  @Description   Free a specific memory segment.
187 
188  @Param[in]     h_Mem - Handle to memory segment.
189 
190  @Return        None.
191 *//***************************************************************************/
192 void MEM_Free(t_Handle h_Mem);
193 
194 /**************************************************************************//**
195  @Function      MEM_Get
196 
197  @Description   Get a block of memory from a segment.
198 
199  @Param[in]     h_Mem - Handle to memory segment.
200 
201  @Return        Pointer to new memory block on success,0 otherwise.
202 *//***************************************************************************/
203 void * MEM_Get(t_Handle h_Mem);
204 
205 /**************************************************************************//**
206  @Function      MEM_GetN
207 
208  @Description   Get up to N blocks of memory from a segment.
209 
210                 The blocks are assumed to be of a fixed size (one size per segment).
211 
212  @Param[in]     h_Mem   - Handle to memory segment.
213  @Param[in]     num     - Number of blocks to allocate.
214  @Param[out]    array   - Array of at least num pointers to which the addresses
215                           of the allocated blocks are written.
216 
217  @Return        The number of blocks actually allocated.
218 
219  @Cautions      Interrupts are disabled for all of the allocation loop.
220                 Although this loop is very short for each block (several machine
221                 instructions), you should not allocate a very large number
222                 of blocks via this routine.
223 *//***************************************************************************/
224 uint16_t MEM_GetN(t_Handle h_Mem, uint32_t num, void *array[]);
225 
226 /**************************************************************************//**
227  @Function      MEM_Put
228 
229  @Description   Put a block of memory back to a segment.
230 
231  @Param[in]     h_Mem   - Handle to memory segment.
232  @Param[in]     p_Block - The block to return.
233 
234  @Return        Pointer to new memory block on success,0 otherwise.
235 *//***************************************************************************/
236 t_Error MEM_Put(t_Handle h_Mem, void *p_Block);
237 
238 /**************************************************************************//**
239  @Function      MEM_ComputePartitionSize
240 
241  @Description   calculate a tight upper boundary of the size of a partition with
242                 given attributes.
243 
244                 The returned value is suitable if one wants to use MEM_InitByAddress().
245 
246  @Param[in]     num         - The number of blocks in the segment.
247  @Param[in]     dataSize    - Size of block to get.
248  @Param[in]     prefixSize  - The prefix size
249  @Param         postfixSize - The postfix size
250  @Param[in]     alignment   - The requested alignment value (in bytes)
251 
252  @Return        The memory block size a segment with the given attributes needs.
253 *//***************************************************************************/
254 uint32_t MEM_ComputePartitionSize(uint32_t num,
255                                   uint16_t dataSize,
256                                   uint16_t prefixSize,
257                                   uint16_t postfixSize,
258                                   uint16_t alignment);
259 
260 #ifdef DEBUG_MEM_LEAKS
261 #if !(defined(__MWERKS__) && (__dest_os == __ppc_eabi))
262 #error  "Memory-Leaks-Debug option is supported only for freescale CodeWarrior"
263 #endif /* !(defined(__MWERKS__) && ... */
264 
265 /**************************************************************************//**
266  @Function      MEM_CheckLeaks
267 
268  @Description   Report MEM object leaks.
269 
270                 This routine is automatically called by the MEM_Free() routine,
271                 but it can also be invoked while the MEM object is alive.
272 
273  @Param[in]     h_Mem - Handle to memory segment.
274 
275  @Return        None.
276 *//***************************************************************************/
277 void MEM_CheckLeaks(t_Handle h_Mem);
278 
279 #else  /* not DEBUG_MEM_LEAKS */
280 #define MEM_CheckLeaks(h_Mem)
281 #endif /* not DEBUG_MEM_LEAKS */
282 
283 /**************************************************************************//**
284  @Description   Get base of MEM
285 *//***************************************************************************/
286 #define MEM_GetBase(h_Mem)             ((t_MemorySegment *)(h_Mem))->p_Bases[0]
287 
288 /**************************************************************************//**
289  @Description   Get size of MEM block
290 *//***************************************************************************/
291 #define MEM_GetSize(h_Mem)             ((t_MemorySegment *)(h_Mem))->dataSize
292 
293 /**************************************************************************//**
294  @Description   Get prefix size of MEM block
295 *//***************************************************************************/
296 #define MEM_GetPrefixSize(h_Mem)       ((t_MemorySegment *)(h_Mem))->prefixSize
297 
298 /**************************************************************************//**
299  @Description   Get postfix size of MEM block
300 *//***************************************************************************/
301 #define MEM_GetPostfixSize(h_Mem)      ((t_MemorySegment *)(h_Mem))->postfixSize
302 
303 /**************************************************************************//**
304  @Description   Get alignment of MEM block (in bytes)
305 *//***************************************************************************/
306 #define MEM_GetAlignment(h_Mem)        ((t_MemorySegment *)(h_Mem))->alignment
307 
308 /**************************************************************************//**
309  @Description   Get the number of blocks in the segment
310 *//***************************************************************************/
311 #define MEM_GetNumOfBlocks(h_Mem)             ((t_MemorySegment *)(h_Mem))->num
312 
313 /** @} */ /* end of MEM group */
314 /** @} */ /* end of etc_id group */
315 
316 
317 #endif /* __MEM_EXT_H */
318