1 /**
2 * @file rm_tree.c
3 *
4 * @brief
5 * Resource Manager Tree Manipulation Source.
6 *
7 * \par
8 * ============================================================================
9 * @n (C) Copyright 2012-2013, Texas Instruments, Inc.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 *
15 * Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 *
18 * Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the
21 * distribution.
22 *
23 * Neither the name of Texas Instruments Incorporated nor the names of
24 * its contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 *
39 * \par
40 */
42 /* Standard includes */
43 #include <string.h>
44 #include <stdbool.h>
46 /* RM external API includes */
47 #include <ti/drv/rm/rm.h>
49 /* RM internal API includes */
50 #include <ti/drv/rm/include/rm_treeloc.h>
52 /* RM OSAL layer */
53 #include <rm_osal.h>
55 /**********************************************************************
56 ********************* NameServer Tree Functions **********************
57 **********************************************************************/
59 /* FUNCTION PURPOSE: Creates a new NameServer tree node
60 ***********************************************************************
61 * DESCRIPTION: Creates a new NameServer tree node with the
62 * specified name and the resource values it is
63 * tied to.
64 */
65 Rm_NameServerNode *rmNameServerNodeNew(Rm_NameServerNodeCfg *nodeCfg)
66 {
67 Rm_NameServerNode *newNode = NULL;
69 newNode = Rm_osalMalloc(sizeof(Rm_NameServerNode));
70 if (newNode) {
71 strncpy(newNode->objName, nodeCfg->objName, RM_NAME_MAX_CHARS);
72 strncpy(newNode->resourceName, nodeCfg->resourceName, RM_NAME_MAX_CHARS);
73 newNode->resourceBase = nodeCfg->resourceBase;
74 newNode->resourceLength = nodeCfg->resourceLength;
75 }
77 return(newNode);
78 }
80 /* FUNCTION PURPOSE: Deletes a NameServer tree node
81 ***********************************************************************
82 * DESCRIPTION: Deletes the specified NameServer tree node.
83 */
84 void rmNameServerNodeFree(Rm_NameServerNode *node)
85 {
86 if (node) {
87 Rm_osalFree((void *)node, sizeof(Rm_NameServerNode));
88 }
89 }
91 /* FUNCTION PURPOSE: Compares two NameServer tree nodes
92 ***********************************************************************
93 * DESCRIPTION: Returns the result of a comparison of two
94 * NameServer tree node names.
95 * node1 name < node2 name --> return < 0
96 * node1 name = node2 name --> return 0
97 * node1 name > node2 name --> return > 0
98 */
99 int rmNameServerNodeCompare(Rm_NameServerNode *node1, Rm_NameServerNode *node2)
100 {
101 return(strncmp(node1->objName, node2->objName, RM_NAME_MAX_CHARS));
102 }
104 /* Generate the NameServer tree manipulation functions */
105 RB_GENERATE(_Rm_NameServerTree, _Rm_NameServerNode, linkage, rmNameServerNodeCompare);
107 /**********************************************************************
108 *************** Policy Valid Instance Tree Functions *****************
109 **********************************************************************/
111 /* FUNCTION PURPOSE: Creates a new valid instance tree node
112 ***********************************************************************
113 * DESCRIPTION: Creates a new valid instance tree node with the
114 * specified name.
115 */
116 Rm_PolicyValidInstNode *rmPolicyValidInstNodeNew(char *instName)
117 {
118 Rm_PolicyValidInstNode *newNode = NULL;
120 newNode = Rm_osalMalloc(sizeof(Rm_PolicyValidInstNode));
122 strncpy(newNode->name, instName, RM_NAME_MAX_CHARS);
123 newNode->allocRefCount = 0;
124 newNode->deletePending = false;
126 return(newNode);
127 }
129 /* FUNCTION PURPOSE: Deletes a valid instance tree node
130 ***********************************************************************
131 * DESCRIPTION: Deletes the specified valind instance tree node
132 * if it has zero allocation references.
133 */
134 void rmPolicyValidInstNodeFree(Rm_PolicyValidInstNode *node)
135 {
136 if (node->allocRefCount == 0) {
137 Rm_osalFree((void *)node, sizeof(Rm_PolicyValidInstNode));
138 }
139 }
141 /* FUNCTION PURPOSE: Compares two valid instance tree nodes
142 ***********************************************************************
143 * DESCRIPTION: Returns the result of a comparison of two
144 * valid instance tree node names.
145 * node1 name < node2 name --> return < 0
146 * node1 name = node2 name --> return 0
147 * node1 name > node2 name --> return > 0
148 */
149 int rmPolicyValidInstNodeCompare(Rm_PolicyValidInstNode *node1, Rm_PolicyValidInstNode *node2)
150 {
151 return(strncmp(node1->name, node2->name, RM_NAME_MAX_CHARS));
152 }
154 /* Generate the valid instance tree manipulation functions */
155 RB_GENERATE(_Rm_PolicyValidInstTree, _Rm_PolicyValidInstNode, linkage, rmPolicyValidInstNodeCompare);
157 /**********************************************************************
158 ***************** Allocator Resource Tree Functions ******************
159 **********************************************************************/
161 /* FUNCTION PURPOSE: Creates a new resource tree node
162 ***********************************************************************
163 * DESCRIPTION: Creates a new resource tree node with the
164 * specified name resource values.
165 */
166 Rm_ResourceNode *rmResourceNodeNew(uint32_t resourceBase, uint32_t resourceLength)
167 {
168 Rm_ResourceNode *newNode = NULL;
170 newNode = Rm_osalMalloc(sizeof(Rm_ResourceNode));
171 memset((void *)newNode, 0, sizeof(Rm_ResourceNode));
173 newNode->base = resourceBase;
174 newNode->length = resourceLength;
175 newNode->allocationCount = 0;
176 newNode->ownerList = NULL;
178 return(newNode);
179 }
181 /* FUNCTION PURPOSE: Deletes a resource tree node
182 ***********************************************************************
183 * DESCRIPTION: Deletes the specified resource tree node
184 * if its allocation count is zero.
185 */
186 void rmResourceNodeFree(Rm_ResourceNode *node)
187 {
188 if (node->allocationCount == 0) {
189 Rm_osalFree((void *)node, sizeof(Rm_ResourceNode));
190 }
191 }
193 /* FUNCTION PURPOSE: Compares two resource tree nodes
194 ***********************************************************************
195 * DESCRIPTION: Returns the result of a comparison of two
196 * resource tree node value ranges.
197 * |node1 range||node2 range| --> return < 0
198 * |node1 range|
199 * |node2 range| --> return 0 (any overlap in ranges)
200 * |node2 range||node1 range| --> return > 0
201 */
202 int rmResourceNodeCompare(Rm_ResourceNode *node1, Rm_ResourceNode *node2)
203 {
204 uint32_t node1End = node1->base + node1->length - 1;
205 uint32_t node2End = node2->base + node2->length - 1;
207 if (node1End < node2->base) {
208 /* End of node1 range is less than the start of node2's range. Return a negative
209 * value */
210 return (-1);
211 }
212 else if (node1->base > node2End) {
213 /* Start of node1 range is after end of node2's range. Return a positive value */
214 return (1);
215 }
216 else {
217 /* If neither of the latter conditions were satisfied there is some overlap between
218 * node1 and node2. Return 0 since the application must handle this overlap. */
219 return (0);
220 }
221 }
223 /* Generate the resource tree manipulation functions */
224 RB_GENERATE(_Rm_AllocatorResourceTree, _Rm_ResourceNode, linkage, rmResourceNodeCompare)