1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /* ---- includes ----------------------------------------------------------- */
18 
19 #include "b_BasicEm/Context.h"
20 #include "b_BasicEm/MemTbl.h"
21 #include "b_BasicEm/Functions.h"
22 
23 /* ------------------------------------------------------------------------- */
24 
25 /* ========================================================================= */
26 /*                                                                           */
27 /* ---- \ghd{ auxiliary functions } ---------------------------------------- */
28 /*                                                                           */
29 /* ========================================================================= */
30 
31 /* ------------------------------------------------------------------------- */
32 
bbs_MemTbl_memOverlap(const uint16 * memPtr1A,uint32 size1A,const uint16 * memPtr2A,uint32 size2A)33 flag bbs_MemTbl_memOverlap( const uint16* memPtr1A, uint32 size1A,
34 						    const uint16* memPtr2A, uint32 size2A )
35 {
36 	int32 diffL = memPtr2A - memPtr1A;
37 	if( diffL >= 0 && diffL < ( int32 )size1A ) return TRUE;
38 	diffL += ( int32 )size2A;
39 	if( diffL >= 0 && diffL < ( int32 )size1A ) return TRUE;
40 	return FALSE;
41 }
42 
43 /* ------------------------------------------------------------------------- */
44 
45 /* ========================================================================= */
46 /*                                                                           */
47 /* ---- \ghd{ constructor / destructor } ----------------------------------- */
48 /*                                                                           */
49 /* ========================================================================= */
50 
51 /* ------------------------------------------------------------------------- */
52 
bbs_MemTbl_init(struct bbs_Context * cpA,struct bbs_MemTbl * ptrA)53 void bbs_MemTbl_init( struct bbs_Context* cpA,
54 					  struct bbs_MemTbl* ptrA )
55 {
56 	uint32 iL;
57 	for( iL = 0; iL < bbs_MAX_MEM_SEGS; iL++ )
58 	{
59 		bbs_MemSeg_init( cpA, &ptrA->esArrE[ iL ] );
60 		bbs_MemSeg_init( cpA, &ptrA->ssArrE[ iL ] );
61 		ptrA->espArrE[ iL ] = NULL;
62 	}
63 	ptrA->esSizeE = 0;
64 	ptrA->ssSizeE = 0;
65 }
66 
67 /* ------------------------------------------------------------------------- */
68 
bbs_MemTbl_exit(struct bbs_Context * cpA,struct bbs_MemTbl * ptrA)69 void bbs_MemTbl_exit( struct bbs_Context* cpA,
70 					  struct bbs_MemTbl* ptrA )
71 {
72 	uint32 iL;
73 	for( iL = 0; iL < bbs_MAX_MEM_SEGS; iL++ )
74 	{
75 		bbs_MemSeg_exit( cpA, &ptrA->esArrE[ iL ] );
76 		bbs_MemSeg_exit( cpA, &ptrA->ssArrE[ iL ] );
77 		ptrA->espArrE[ iL ] = NULL;
78 	}
79 	ptrA->esSizeE = 0;
80 	ptrA->ssSizeE = 0;
81 }
82 
83 /* ------------------------------------------------------------------------- */
84 
85 /* ========================================================================= */
86 /*                                                                           */
87 /* ---- \ghd{ operators } -------------------------------------------------- */
88 /*                                                                           */
89 /* ========================================================================= */
90 
91 /* ------------------------------------------------------------------------- */
92 
93 /* ========================================================================= */
94 /*                                                                           */
95 /* ---- \ghd{ query functions } -------------------------------------------- */
96 /*                                                                           */
97 /* ========================================================================= */
98 
99 /* ------------------------------------------------------------------------- */
100 
bbs_MemTbl_overlap(struct bbs_Context * cpA,struct bbs_MemTbl * ptrA,const void * memPtrA,uint32 sizeA)101 flag bbs_MemTbl_overlap( struct bbs_Context* cpA,
102 						 struct bbs_MemTbl* ptrA,
103 						 const void* memPtrA, uint32 sizeA )
104 {
105 	uint32 iL;
106 	for( iL = 0; iL < ptrA->esSizeE; iL++ )
107 	{
108 		if( bbs_MemTbl_memOverlap( ptrA->espArrE[ iL ]->memPtrE,
109 								   ptrA->espArrE[ iL ]->sizeE,
110 								   memPtrA, sizeA ) )
111 		{
112 			return TRUE;
113 		}
114 	}
115 
116 	for( iL = 0; iL < ptrA->ssSizeE; iL++ )
117 	{
118 		if( bbs_MemTbl_memOverlap( ptrA->ssArrE[ iL ].memPtrE,
119 								   ptrA->ssArrE[ iL ].sizeE,
120 								   memPtrA, sizeA ) )
121 		{
122 			return TRUE;
123 		}
124 	}
125 
126 	return FALSE;
127 }
128 
129 /* ------------------------------------------------------------------------- */
130 
131 /* ========================================================================= */
132 /*                                                                           */
133 /* ---- \ghd{ modify functions } ------------------------------------------- */
134 /*                                                                           */
135 /* ========================================================================= */
136 
137 /* ------------------------------------------------------------------------- */
138 
139 /* ========================================================================= */
140 /*                                                                           */
141 /* ---- \ghd{ I/O } -------------------------------------------------------- */
142 /*                                                                           */
143 /* ========================================================================= */
144 
145 /* ------------------------------------------------------------------------- */
146 
147 /* ========================================================================= */
148 /*                                                                           */
149 /* ---- \ghd{ exec functions } --------------------------------------------- */
150 /*                                                                           */
151 /* ========================================================================= */
152 
153 /* ------------------------------------------------------------------------- */
154 
bbs_MemTbl_create(struct bbs_Context * cpA,struct bbs_MemTbl * ptrA,void * memPtrA,uint32 sizeA,uint32 sharedSubSizeA)155 void bbs_MemTbl_create( struct bbs_Context* cpA,
156 					    struct bbs_MemTbl* ptrA,
157 						void* memPtrA,
158 						uint32 sizeA,
159 						uint32 sharedSubSizeA )
160 {
161 	if( sharedSubSizeA > sizeA )
162 	{
163 		bbs_ERROR0( "struct bbs_MemTbl bbs_MemTbl_create( void* memPtrA, uint32 sizeA, uint32 sharedSubSizeA ):\n"
164 			       "sharedSubSizeA > sizeA" );
165 		return;
166 	}
167 	bbs_MemTbl_init( cpA, ptrA );
168 
169 
170 	ptrA->esArrE[ 0 ] = bbs_MemSeg_create( cpA, memPtrA, sizeA - sharedSubSizeA );
171 	#ifdef HW_TMS320C5x
172 		ptrA->ssArrE[ 0 ] = bbs_MemSeg_createShared( cpA, ( uint16* ) ( ( int32 ) ( ( uint16* )memPtrA ) + sizeA - sharedSubSizeA ), sharedSubSizeA );
173 	#else
174 		ptrA->ssArrE[ 0 ] = bbs_MemSeg_createShared( cpA, ( uint16* )memPtrA + sizeA - sharedSubSizeA, sharedSubSizeA );
175 	#endif
176 	ptrA->espArrE[ 0 ] = &ptrA->esArrE[ 0 ];
177 
178 	ptrA->esSizeE = 1;
179 	ptrA->ssSizeE = 1;
180 }
181 
182 /* ------------------------------------------------------------------------- */
183 
bbs_MemTbl_add(struct bbs_Context * cpA,struct bbs_MemTbl * ptrA,void * memPtrA,uint32 sizeA,uint32 idA)184 void bbs_MemTbl_add( struct bbs_Context* cpA,
185 					 struct bbs_MemTbl* ptrA,
186 					 void* memPtrA,
187 					 uint32 sizeA,
188 					 uint32 idA )
189 {
190 	if( ptrA->esSizeE == bbs_MAX_MEM_SEGS )
191 	{
192 		bbs_ERROR0( "void bbs_MemTbl_add( struct bbs_MemTbl* ptrA, void* memPtrA, uint32 sizeA ):\n"
193 			       "Table is full! Increase constant bbs_MAX_MEM_SEGS" );
194 		return;
195 	}
196 	ptrA->esArrE[ ptrA->esSizeE ] = bbs_MemSeg_create( cpA, memPtrA, sizeA );
197 	ptrA->esArrE[ ptrA->esSizeE ].idE = idA;
198 	ptrA->espArrE[ ptrA->esSizeE ] = &ptrA->esArrE[ ptrA->esSizeE ];
199 	ptrA->esSizeE++;
200 }
201 
202 /* ------------------------------------------------------------------------- */
203 
bbs_MemTbl_addShared(struct bbs_Context * cpA,struct bbs_MemTbl * ptrA,void * memPtrA,uint32 sizeA,uint32 idA)204 void bbs_MemTbl_addShared( struct bbs_Context* cpA,
205 						   struct bbs_MemTbl* ptrA,
206 						   void* memPtrA,
207 						   uint32 sizeA,
208 						   uint32 idA )
209 {
210 	if( ptrA->ssSizeE == bbs_MAX_MEM_SEGS )
211 	{
212 		bbs_ERROR0( "void bbs_MemTbl_addShared( struct bbs_MemTbl* ptrA, void* memPtrA, uint32 sizeA ):\n"
213 			       "Table is full! Increase constant bbs_MAX_MEM_SEGS" );
214 		return;
215 	}
216 	ptrA->ssArrE[ ptrA->ssSizeE ] = bbs_MemSeg_createShared( cpA, memPtrA, sizeA );
217 	ptrA->ssArrE[ ptrA->ssSizeE ].idE = idA;
218 	ptrA->ssSizeE++;
219 }
220 
221 /* ------------------------------------------------------------------------- */
222 
bbs_MemTbl_segPtr(struct bbs_Context * cpA,struct bbs_MemTbl * ptrA,uint32 idA)223 struct bbs_MemSeg* bbs_MemTbl_segPtr( struct bbs_Context* cpA,
224 									  struct bbs_MemTbl* ptrA,
225 									  uint32 idA )
226 {
227 	uint32 iL;
228 	if( ptrA->esSizeE == 0 )
229 	{
230 		bbs_ERROR0( "bbs_MemTbl_segPtr(): Table contains no exclusive segments." );
231 		return NULL;
232 	}
233 	if( idA > 0 )
234 	{
235 		for( iL = 0; iL < ptrA->esSizeE; iL++ )
236 		{
237 			if( idA == ptrA->espArrE[ iL ]->idE ) return ptrA->espArrE[ iL ];
238 		}
239 	}
240 	for( iL = 0; iL < ptrA->esSizeE; iL++ )
241 	{
242 		if( ptrA->espArrE[ iL ]->sizeE > 0 ||
243 			ptrA->espArrE[ iL ]->dynMemManagerPtrE != 0 )
244 		{
245 			return ptrA->espArrE[ iL ];
246 		}
247 	}
248 	bbs_ERR0( bbs_ERR_MEMORY_OVERFLOW,
249 			  "bbs_MemTbl_segPtr(): Table contains no valid exclusive segments." );
250 	return 0;
251 }
252 
253 /* ------------------------------------------------------------------------- */
254 
bbs_MemTbl_sharedSegPtr(struct bbs_Context * cpA,struct bbs_MemTbl * ptrA,uint32 idA)255 struct bbs_MemSeg* bbs_MemTbl_sharedSegPtr( struct bbs_Context* cpA,
256 										    struct bbs_MemTbl* ptrA,
257 											uint32 idA )
258 {
259 	uint32 iL;
260 	if( ptrA->ssSizeE == 0 )
261 	{
262 		bbs_ERROR0( "bbs_MemTbl_sharedSegPtr(): Table contains no shared segments." );
263 		return NULL;
264 	}
265 	if( idA > 0 )
266 	{
267 		for( iL = 0; iL < ptrA->ssSizeE; iL++ )
268 		{
269 			if( idA == ptrA->ssArrE[ iL ].idE ) return &ptrA->ssArrE[ iL ];
270 		}
271 	}
272 	for( iL = 0; iL < ptrA->ssSizeE; iL++ )
273 	{
274 		if( ptrA->ssArrE[ iL ].sizeE > 0 ||
275 			ptrA->ssArrE[ iL ].dynMemManagerPtrE != 0 )
276 		{
277 			return &ptrA->ssArrE[ iL ];
278 		}
279 	}
280 	bbs_ERR0( bbs_ERR_MEMORY_OVERFLOW,
281 			  "bbs_MemTbl_sharedSegPtr(): Table contains no valid shared segments." );
282 	return 0;
283 }
284 
285 /* ------------------------------------------------------------------------- */
286 
bbs_MemTbl_fastestSegPtr(struct bbs_Context * cpA,struct bbs_MemTbl * ptrA,uint32 minSizeA)287 struct bbs_MemSeg* bbs_MemTbl_fastestSegPtr( struct bbs_Context* cpA,
288 											 struct bbs_MemTbl* ptrA,
289 											 uint32 minSizeA )
290 {
291 	uint32 iL;
292 	for( iL = 0; iL < ptrA->esSizeE; iL++ )
293 	{
294 		if( bbs_MemSeg_availableSize( cpA, ptrA->espArrE[ iL ] ) >= minSizeA ) break;
295 	}
296 	if( iL == ptrA->esSizeE )
297 	{
298 		if( ptrA->esSizeE == 0 )
299 		{
300 			bbs_ERROR0( "struct bbs_MemSeg* bbs_MemTbl_fastestSegPtr( struct bbs_MemTbl* ptrA, uint32 minSizeA ):\n"
301 					   "Table contains no exclusive segments" );
302 			return NULL;
303 		}
304 		else
305 		{
306 			bbs_ERR0( bbs_ERR_MEMORY_OVERFLOW,
307 					  "struct bbs_MemSeg* bbs_MemTbl_fastestSegPtr( struct bbs_MemTbl* ptrA, uint32 minSizeA ):\n"
308 					  "Could not find segment with sufficient free space" );
309 			return NULL;
310 		}
311 	}
312 	if( ptrA->espArrE[ iL ]->sharedE )
313 	{
314 		bbs_ERROR0( "struct bbs_MemSeg* bbs_MemTbl_fastestSegPtr( struct bbs_MemTbl* ptrA, uint32 minSizeA ):\n"
315 			       "Table corrupt: Found shared segment in exclusive table" );
316 		return NULL;
317 	}
318 
319 	return ptrA->espArrE[ iL ];
320 }
321 
322 /* ------------------------------------------------------------------------- */
323 
bbs_MemTbl_largestSegPtr(struct bbs_Context * cpA,struct bbs_MemTbl * ptrA)324 struct bbs_MemSeg* bbs_MemTbl_largestSegPtr( struct bbs_Context* cpA,
325 											 struct bbs_MemTbl* ptrA )
326 {
327 	uint32 iL;
328 	uint32 maxIndexL = 0;
329 	uint32 maxSizeL = 0;
330 
331 	if( ptrA->esSizeE == 0 )
332 	{
333 		bbs_ERROR0( "struct bbs_MemSeg* bbs_MemTbl_largestSegPtr( struct bbs_MemTbl* ptrA ):\n"
334 			       "No exclusive segments available" );
335 		return NULL;
336 	}
337 
338 	for( iL = 0; iL < ptrA->esSizeE; iL++ )
339 	{
340 		uint32 sizeL = bbs_MemSeg_availableSize( cpA, ptrA->espArrE[ iL ] );
341 		if( sizeL > maxSizeL )
342 		{
343 			maxSizeL = sizeL;
344 			maxIndexL = iL;
345 		}
346 	}
347 
348 	if( ptrA->espArrE[ maxIndexL ]->sharedE )
349 	{
350 		bbs_ERROR0( "struct bbs_MemSeg* bbs_MemTbl_largestSegPtr( struct bbs_MemTbl* ptrA ):\n"
351 			       "Table corrupt: Found shared segment in exclusive table" );
352 		return NULL;
353 	}
354 
355 	return ptrA->espArrE[ maxIndexL ];
356 }
357 
358 /* ------------------------------------------------------------------------- */
359 
bbs_MemTbl_fastestSharedSegPtr(struct bbs_Context * cpA,struct bbs_MemTbl * ptrA,uint32 minSizeA)360 struct bbs_MemSeg* bbs_MemTbl_fastestSharedSegPtr( struct bbs_Context* cpA,
361 												   struct bbs_MemTbl* ptrA,
362 												   uint32 minSizeA )
363 {
364 	uint32 iL;
365 	for( iL = 0; iL < ptrA->ssSizeE; iL++ )
366 	{
367 		if( bbs_MemSeg_availableSize( cpA, &ptrA->ssArrE[ iL ] ) >= minSizeA ) break;
368 	}
369 	if( iL == ptrA->ssSizeE )
370 	{
371 		if( ptrA->esSizeE == 0 )
372 		{
373 			bbs_ERROR0( "struct bbs_MemSeg* bbs_MemTbl_fastestSegPtr( struct bbs_MemTbl* ptrA, uint32 minSizeA ):\n"
374 					   "Table contains no shared segments" );
375 			return NULL;
376 		}
377 		else
378 		{
379 			bbs_ERR0( bbs_ERR_MEMORY_OVERFLOW,
380 					  "struct bbs_MemSeg* bbs_MemTbl_fastestSharedSegPtr( struct bbs_MemTbl* ptrA, uint32 minSizeA ):\n"
381 					  "Could not find segment with sufficient free space" );
382 			return NULL;
383 		}
384 	}
385 	if( !ptrA->ssArrE[ iL ].sharedE )
386 	{
387 		bbs_ERROR0( "struct bbs_MemSeg* bbs_MemTbl_fastestSharedSegPtr( struct bbs_MemTbl* ptrA, uint32 minSizeA ):\n"
388 			       "Table corrupt: Found exclusive segment in shared table" );
389 		return NULL;
390 	}
391 
392 	return &ptrA->ssArrE[ iL ];
393 }
394 
395 /* ------------------------------------------------------------------------- */
396 
bbs_MemTbl_largestSharedSegPtr(struct bbs_Context * cpA,struct bbs_MemTbl * ptrA)397 struct bbs_MemSeg* bbs_MemTbl_largestSharedSegPtr( struct bbs_Context* cpA,
398 												   struct bbs_MemTbl* ptrA )
399 {
400 	uint32 iL;
401 	uint32 maxIndexL = 0;
402 	uint32 maxSizeL = 0;
403 
404 	if( ptrA->ssSizeE == 0 )
405 	{
406 		bbs_ERROR0( "struct bbs_MemSeg* bbs_MemTbl_largestSharedSegPtr( struct bbs_MemTbl* ptrA ):\n"
407 			       "No shared segments available" );
408 		return NULL;
409 	}
410 
411 	for( iL = 0; iL < ptrA->ssSizeE; iL++ )
412 	{
413 		uint32 sizeL = bbs_MemSeg_availableSize( cpA, &ptrA->ssArrE[ iL ] );
414 		if( sizeL > maxSizeL )
415 		{
416 			maxSizeL = sizeL;
417 			maxIndexL = iL;
418 		}
419 	}
420 
421 	if( !ptrA->ssArrE[ maxIndexL ].sharedE )
422 	{
423 		bbs_ERROR0( "struct bbs_MemSeg* bbs_MemTbl_largestSharedSegPtr( struct bbs_MemTbl* ptrA ):\n"
424 			       "Table corrupt: Found exclusive segment in shared table" );
425 		return NULL;
426 	}
427 
428 	return &ptrA->ssArrE[ maxIndexL ];
429 }
430 
431 /* ------------------------------------------------------------------------- */
432 
433 /* ========================================================================= */
434 
435 
436