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
33flag 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
53void 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
69void 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
101flag 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
155void 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
184void 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
204void 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
223struct 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
255struct 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
287struct 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
324struct 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
360struct 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
397struct 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