1 /*******************************************************************************
2 * Copyright (C) 2018 Cadence Design Systems, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to use this Software with Cadence processor cores only and
7 * not with any other processors and platforms, subject to
8 * the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included
11 * in all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
15 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
17 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
18 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
19 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 
21 ******************************************************************************/
22 
23 /*******************************************************************************
24  * xf-mm.h
25  *
26  * Generic dynamic memory manager (based on rb-tree index)
27  *
28  *******************************************************************************/
29 
30 #ifndef __XF_H
31 #error "xf-mem.h mustn't be included directly"
32 #endif
33 
34 /*******************************************************************************
35  * Includes
36  ******************************************************************************/
37 
38 /* ...red-black trees library */
39 #include "lib/rbtree.h"
40 
41 /*******************************************************************************
42  * Cache-line aligned types
43  ******************************************************************************/
44 
45 /* ...proper cache-line alignment */
46 #define XF_ALIGNED(size)                            \
47     (((size) + XF_PROXY_ALIGNMENT - 1) & ~(XF_PROXY_ALIGNMENT - 1))
48 
49 /* ...cache-line aligned type identifier */
50 #define XF_ALIGNED_TYPE(type)                       \
51     __xf_aligned_##type
52 
53 /* ...definition of cache-line aligned type */
54 #define XF_ALIGNED_TYPEDEF(type, name)              \
55 typedef union                                       \
56 {                                                   \
57     /* ...item of original type */                  \
58     type        __obj;                              \
59                                                     \
60     /* ...padding to cache-line */                  \
61     u8          __pad[XF_ALIGNED(sizeof(type))];    \
62                                                     \
63 }   XF_ALIGNED_TYPE(type), name __xf_shmem__
64 
65 /* ...accessor to original type */
66 #define XF_ALIGNED_OBJ(p)                           \
67     (&(p)->__obj)
68 
69 #define XF_IS_ALIGNED(p)                            \
70     (((u32)(p) & (XF_PROXY_ALIGNMENT - 1)) == 0)
71 
72 /*******************************************************************************
73  * Memory pool description
74  ******************************************************************************/
75 
76 /* ...memory allocator data */
77 typedef struct xf_mm_pool
78 {
79     /* ...free blocks map sorted by block length */
80     rb_tree_t       l_map;
81 
82     /* ...free blocks map sorted by address of the block */
83     rb_tree_t       a_map;
84 
85     /* ...address of memory pool (32-bytes aligned at least); need that? - tbd */
86     void           *addr;
87 
88     /* ...length of the pool (multiple of descriptor size); need that? - tbd */
89     u32             size;
90 
91 }   xf_mm_pool_t;
92 
93 /* ...descriptor of free memory block */
94 typedef struct xf_mm_block
95 {
96     /* ...rb-tree node in a block-length map */
97     rb_node_t       l_node;
98 
99     /* ...rb-tree node in a block-address map */
100     rb_node_t       a_node;
101 
102 }   xf_mm_block_t;
103 
104 /* ...properly aligned allocation unit */
105 typedef u8 xf_mm_item[xf_next_power_of_two(sizeof(xf_mm_block_t))];
106 
107 /* ...macro to assure proper alignment of dynamically allocated data */
108 #define XF_MM(size)         (((size) + sizeof(xf_mm_item) - 1) & ~(sizeof(xf_mm_item) - 1))
109 
110 /* ...check if memory is properly aligned */
111 #define XF_MM_ALIGNED(size) (!((size) & (sizeof(xf_mm_item) - 1)))
112 
113 /* ...alignement definition */
114 #define __xf_mm__  __attribute__((__aligned__(sizeof(xf_mm_item))))
115 
116 /*******************************************************************************
117  * Dynamically allocated buffer
118  ******************************************************************************/
119 
120 /* ...memory allocation metadata */
121 typedef struct xf_mm_buffer
122 {
123     /* ...allocation address */
124     void           *addr;
125 
126     /* ...length */
127     u32             size;
128 
129 }   __xf_mm__ xf_mm_buffer_t;
130 
131 /*******************************************************************************
132  * API functions
133  ******************************************************************************/
134 
135 /* ...pool initialization */
136 extern int      xf_mm_init(xf_mm_pool_t *pool, void *addr, u32 size);
137 
138 /* ...block allocation */
139 extern void *   xf_mm_alloc(xf_mm_pool_t *pool, u32 size);
140 
141 /* ...block deallocation */
142 extern void     xf_mm_free(xf_mm_pool_t *pool, void *addr, u32 size);
143