xref: /freebsd/sys/contrib/ncsw/inc/etc/mem_ext.h (revision 2e3f49888ec8851bafb22011533217487764fdb0)
1 /* Copyright (c) 2008-2012 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 
36  @File          mem_ext.h
37 
38  @Description   External prototypes for the memory manager object
39 *//***************************************************************************/
40 
41 #ifndef __MEM_EXT_H
42 #define __MEM_EXT_H
43 
44 #include "std_ext.h"
45 #include "part_ext.h"
46 
47 
48 /**************************************************************************//**
49  @Group         etc_id   Utility Library Application Programming Interface
50 
51  @Description   External routines.
52 
53  @{
54 *//***************************************************************************/
55 
56 /**************************************************************************//**
57  @Group         mem_id   Slab Memory Manager
58 
59  @Description   Slab Memory Manager module functions, definitions and enums.
60 
61  @{
62 *//***************************************************************************/
63 
64 /* Each block is of the following structure:
65  *
66  *
67  *  +-----------+----------+---------------------------+-----------+-----------+
68  *  | Alignment |  Prefix  | Data                      | Postfix   | Alignment |
69  *  |  field    |   field  |  field                    |   field   | Padding   |
70  *  |           |          |                           |           |           |
71  *  +-----------+----------+---------------------------+-----------+-----------+
72  *  and at the beginning of all bytes, an additional optional padding might reside
73  *  to ensure that the first blocks data field is aligned as requested.
74  */
75 
76 
77 #define MEM_MAX_NAME_LENGTH     8
78 
79 /**************************************************************************//*
80  @Description   Memory Segment structure
81 *//***************************************************************************/
82 
83 typedef struct
84 {
85     char        name[MEM_MAX_NAME_LENGTH];
86                                     /* The segment's name */
87     uint8_t     **p_Bases;          /* Base addresses of the segments */
88     uint8_t     **p_BlocksStack;    /* Array of pointers to blocks */
89     t_Handle    h_Spinlock;
90     uint16_t    dataSize;           /* Size of each data block */
91     uint16_t    prefixSize;         /* How many bytes to reserve before the data */
92     uint16_t    postfixSize;        /* How many bytes to reserve after the data */
93     uint16_t    alignment;          /* Requested alignment for the data field */
94     int         allocOwner;         /* Memory allocation owner */
95     uint32_t    getFailures;        /* Number of times get failed */
96     uint32_t    num;                /* Number of blocks in segment */
97     uint32_t    current;            /* Current block */
98     bool        consecutiveMem;     /* Allocate consecutive data blocks memory */
99 #ifdef DEBUG_MEM_LEAKS
100     void        *p_MemDbg;          /* MEM debug database (MEM leaks detection) */
101     uint32_t    blockOffset;
102     uint32_t    blockSize;
103 #endif /* DEBUG_MEM_LEAKS */
104 } t_MemorySegment;
105 
106 
107 
108 /**************************************************************************//**
109  @Function      MEM_Init
110 
111  @Description   Create a new memory segment.
112 
113  @Param[in]     name        - Name of memory partition.
114  @Param[in]     p_Handle    - Handle to new segment is returned through here.
115  @Param[in]     num         - Number of blocks in new segment.
116  @Param[in]     dataSize    - Size of blocks in segment.
117  @Param[in]     prefixSize  - How many bytes to allocate before the data.
118  @Param[in]     postfixSize - How many bytes to allocate after the data.
119  @Param[in]     alignment   - Requested alignment for data field (in bytes).
120 
121  @Return        E_OK - success, E_NO_MEMORY - out of memory.
122 *//***************************************************************************/
123 t_Error MEM_Init(char     name[],
124                  t_Handle *p_Handle,
125                  uint32_t num,
126                  uint16_t dataSize,
127                  uint16_t prefixSize,
128                  uint16_t postfixSize,
129                  uint16_t alignment);
130 
131 /**************************************************************************//**
132  @Function      MEM_InitSmart
133 
134  @Description   Create a new memory segment.
135 
136  @Param[in]     name            - Name of memory partition.
137  @Param[in]     p_Handle        - Handle to new segment is returned through here.
138  @Param[in]     num             - Number of blocks in new segment.
139  @Param[in]     dataSize        - Size of blocks in segment.
140  @Param[in]     prefixSize      - How many bytes to allocate before the data.
141  @Param[in]     postfixSize     - How many bytes to allocate after the data.
142  @Param[in]     alignment       - Requested alignment for data field (in bytes).
143  @Param[in]     memPartitionId  - Memory partition ID for allocation.
144  @Param[in]     consecutiveMem  - Whether to allocate the memory blocks
145                                   continuously or not.
146 
147  @Return        E_OK - success, E_NO_MEMORY - out of memory.
148 *//***************************************************************************/
149 t_Error MEM_InitSmart(char      name[],
150                       t_Handle  *p_Handle,
151                       uint32_t  num,
152                       uint16_t  dataSize,
153                       uint16_t  prefixSize,
154                       uint16_t  postfixSize,
155                       uint16_t  alignment,
156                       uint8_t   memPartitionId,
157                       bool      consecutiveMem);
158 
159 /**************************************************************************//**
160  @Function      MEM_InitByAddress
161 
162  @Description   Create a new memory segment with a specified base address.
163 
164  @Param[in]     name        - Name of memory partition.
165  @Param[in]     p_Handle    - Handle to new segment is returned through here.
166  @Param[in]     num         - Number of blocks in new segment.
167  @Param[in]     dataSize    - Size of blocks in segment.
168  @Param[in]     prefixSize  - How many bytes to allocate before the data.
169  @Param[in]     postfixSize - How many bytes to allocate after the data.
170  @Param[in]     alignment   - Requested alignment for data field (in bytes).
171  @Param[in]     address     - The required base address.
172 
173  @Return        E_OK - success, E_NO_MEMORY - out of memory.
174  *//***************************************************************************/
175 t_Error MEM_InitByAddress(char        name[],
176                           t_Handle    *p_Handle,
177                           uint32_t    num,
178                           uint16_t    dataSize,
179                           uint16_t    prefixSize,
180                           uint16_t    postfixSize,
181                           uint16_t    alignment,
182                           uint8_t     *address);
183 
184 /**************************************************************************//**
185  @Function      MEM_Free
186 
187  @Description   Free a specific memory segment.
188 
189  @Param[in]     h_Mem - Handle to memory segment.
190 
191  @Return        None.
192 *//***************************************************************************/
193 void MEM_Free(t_Handle h_Mem);
194 
195 /**************************************************************************//**
196  @Function      MEM_Get
197 
198  @Description   Get a block of memory from a segment.
199 
200  @Param[in]     h_Mem - Handle to memory segment.
201 
202  @Return        Pointer to new memory block on success,0 otherwise.
203 *//***************************************************************************/
204 void * MEM_Get(t_Handle h_Mem);
205 
206 /**************************************************************************//**
207  @Function      MEM_GetN
208 
209  @Description   Get up to N blocks of memory from a segment.
210 
211                 The blocks are assumed to be of a fixed size (one size per segment).
212 
213  @Param[in]     h_Mem   - Handle to memory segment.
214  @Param[in]     num     - Number of blocks to allocate.
215  @Param[out]    array   - Array of at least num pointers to which the addresses
216                           of the allocated blocks are written.
217 
218  @Return        The number of blocks actually allocated.
219 
220  @Cautions      Interrupts are disabled for all of the allocation loop.
221                 Although this loop is very short for each block (several machine
222                 instructions), you should not allocate a very large number
223                 of blocks via this routine.
224 *//***************************************************************************/
225 uint16_t MEM_GetN(t_Handle h_Mem, uint32_t num, void *array[]);
226 
227 /**************************************************************************//**
228  @Function      MEM_Put
229 
230  @Description   Put a block of memory back to a segment.
231 
232  @Param[in]     h_Mem   - Handle to memory segment.
233  @Param[in]     p_Block - The block to return.
234 
235  @Return        Pointer to new memory block on success,0 otherwise.
236 *//***************************************************************************/
237 t_Error MEM_Put(t_Handle h_Mem, void *p_Block);
238 
239 /**************************************************************************//**
240  @Function      MEM_ComputePartitionSize
241 
242  @Description   calculate a tight upper boundary of the size of a partition with
243                 given attributes.
244 
245                 The returned value is suitable if one wants to use MEM_InitByAddress().
246 
247  @Param[in]     num         - The number of blocks in the segment.
248  @Param[in]     dataSize    - Size of block to get.
249  @Param[in]     prefixSize  - The prefix size
250  @Param         postfixSize - The postfix size
251  @Param[in]     alignment   - The requested alignment value (in bytes)
252 
253  @Return        The memory block size a segment with the given attributes needs.
254 *//***************************************************************************/
255 uint32_t MEM_ComputePartitionSize(uint32_t num,
256                                   uint16_t dataSize,
257                                   uint16_t prefixSize,
258                                   uint16_t postfixSize,
259                                   uint16_t alignment);
260 
261 #ifdef DEBUG_MEM_LEAKS
262 #if !((defined(__MWERKS__) || defined(__GNUC__)) && (__dest_os == __ppc_eabi))
263 #error  "Memory-Leaks-Debug option is supported only for freescale CodeWarrior"
264 #endif /* !(defined(__MWERKS__) && ... */
265 
266 /**************************************************************************//**
267  @Function      MEM_CheckLeaks
268 
269  @Description   Report MEM object leaks.
270 
271                 This routine is automatically called by the MEM_Free() routine,
272                 but it can also be invoked while the MEM object is alive.
273 
274  @Param[in]     h_Mem - Handle to memory segment.
275 
276  @Return        None.
277 *//***************************************************************************/
278 void MEM_CheckLeaks(t_Handle h_Mem);
279 
280 #else  /* not DEBUG_MEM_LEAKS */
281 #define MEM_CheckLeaks(h_Mem)
282 #endif /* not DEBUG_MEM_LEAKS */
283 
284 /**************************************************************************//**
285  @Description   Get base of MEM
286 *//***************************************************************************/
287 #define MEM_GetBase(h_Mem)             ((t_MemorySegment *)(h_Mem))->p_Bases[0]
288 
289 /**************************************************************************//**
290  @Description   Get size of MEM block
291 *//***************************************************************************/
292 #define MEM_GetSize(h_Mem)             ((t_MemorySegment *)(h_Mem))->dataSize
293 
294 /**************************************************************************//**
295  @Description   Get prefix size of MEM block
296 *//***************************************************************************/
297 #define MEM_GetPrefixSize(h_Mem)       ((t_MemorySegment *)(h_Mem))->prefixSize
298 
299 /**************************************************************************//**
300  @Description   Get postfix size of MEM block
301 *//***************************************************************************/
302 #define MEM_GetPostfixSize(h_Mem)      ((t_MemorySegment *)(h_Mem))->postfixSize
303 
304 /**************************************************************************//**
305  @Description   Get alignment of MEM block (in bytes)
306 *//***************************************************************************/
307 #define MEM_GetAlignment(h_Mem)        ((t_MemorySegment *)(h_Mem))->alignment
308 
309 /**************************************************************************//**
310  @Description   Get the number of blocks in the segment
311 *//***************************************************************************/
312 #define MEM_GetNumOfBlocks(h_Mem)             ((t_MemorySegment *)(h_Mem))->num
313 
314 /** @} */ /* end of MEM group */
315 /** @} */ /* end of etc_id group */
316 
317 
318 #endif /* __MEM_EXT_H */
319