comparison gpf/osl/os_mem_fl.c @ 0:75a11d740a02

initial import of gsm-fw from freecalypso-sw rev 1033:5ab737ac3ad7
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 09 Jun 2016 00:02:41 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:75a11d740a02
1 /*
2 * This C module is a reconstruction based on the disassembly of
3 * os_mem.obj in frame_na7_db_fl.lib from the Leonardo package.
4 */
5
6 /* set of included headers from COFF symtab: */
7 #include <stdio.h>
8 #include <string.h>
9 #include "gpfconf.h" /* FreeCalypso addition */
10 #include "../../nucleus/nucleus.h"
11 #include "typedefs.h"
12 #include "os.h"
13 #include "gdi.h"
14 #include "os_types.h"
15 #include "os_glob.h"
16
17 extern T_OS_PART_GRP_TABLE_ENTRY PartGrpTable[];
18 extern T_OS_MEM_POOL_TABLE_ENTRY MemPoolTable[];
19 extern T_OS_POOL_BORDER PoolBorder[];
20
21 OS_HANDLE os_ext_pool_handle;
22 OS_HANDLE os_int_pool_handle;
23
24 static USHORT NumOfMemoryPools;
25 static NU_SEMAPHORE MemSemCB;
26 static NU_MEMORY_POOL mem_pool_head;
27
28 GLOBAL LONG
29 os_SetPoolHandles(OS_HANDLE ext_pool_handle, OS_HANDLE int_pool_handle)
30 {
31 os_ext_pool_handle = ext_pool_handle;
32 os_int_pool_handle = int_pool_handle;
33 return(OS_OK);
34 }
35
36 static int
37 os_GetPartitionPoolEntry(USHORT Index, T_OS_PART_POOL **pool)
38 {
39 static T_OS_PART_POOL *part_pool;
40 static int grp_hndl;
41
42 switch (Index) {
43 case FIRST_ENTRY:
44 grp_hndl = 0;
45 *pool = part_pool = PartGrpTable[0].grp_head;
46 return(OS_OK);
47 case NEXT_ENTRY:
48 if (part_pool->next) {
49 *pool = part_pool = part_pool->next;
50 return(OS_OK);
51 }
52 grp_hndl++;
53 if (PartGrpTable[grp_hndl].grp_head) {
54 *pool = part_pool = PartGrpTable[grp_hndl].grp_head;
55 return(OS_OK);
56 } else
57 return(OS_ERROR);
58 default:
59 return(OS_ERROR);
60 }
61 }
62
63 GLOBAL LONG
64 os_PartitionInformation(USHORT Handle, char *Buffer)
65 {
66 T_OS_PART_POOL *pool;
67 OPTION SuspendType;
68 UNSIGNED PoolSize;
69 UNSIGNED PartitionSize;
70 UNSIGNED Available;
71 UNSIGNED Waiting;
72 UNSIGNED Allocated;
73 VOID *pStartAddress;
74 NU_TASK *First;
75 CHAR Name[NU_MAX_NAME];
76
77 if (os_GetPartitionPoolEntry(Handle, &pool) == OS_ERROR)
78 return(OS_ERROR);
79 if (NU_Partition_Pool_Information(&pool->pcb, Name, &pStartAddress,
80 &PoolSize, &PartitionSize, &Available,
81 &Allocated, &SuspendType, &Waiting,
82 &First)
83 != NU_SUCCESS)
84 return(OS_ERROR);
85 sprintf(Buffer,
86 "Name:%s Addr:%lx PoolSize:%ld PartSize:%ld Free:%ld Used:%ld",
87 Name, (UNSIGNED) pStartAddress, PoolSize, PartitionSize,
88 Available, Allocated);
89 return(OS_OK);
90 }
91
92 static int
93 os_GetMemoryPoolEntry(USHORT Index, OS_HANDLE *Handle)
94 {
95 static USHORT Idx;
96
97 switch (Index) {
98 case FIRST_ENTRY:
99 Idx = 0;
100 break;
101 case NEXT_ENTRY:
102 Idx++;
103 break;
104 default:
105 Idx = Index;
106 }
107 if (Idx == NumOfMemoryPools)
108 return(OS_ERROR);
109 *Handle = Idx;
110 return(OS_OK);
111 }
112
113 GLOBAL LONG
114 os_MemoryInformation(USHORT Index, char *Buffer)
115 {
116 OS_HANDLE Handle;
117 OPTION SuspendType;
118 UNSIGNED Size, Min, Available, Waiting;
119 VOID *pStartAddress;
120 NU_TASK *First;
121 CHAR Name[NU_MAX_NAME];
122
123 if (os_GetMemoryPoolEntry(Index, &Handle) == OS_ERROR)
124 return(OS_ERROR);
125 if (NU_Memory_Pool_Information(MemPoolTable[Handle].pcb, Name,
126 &pStartAddress, &Size, &Min,
127 &Available, &SuspendType, &Waiting,
128 &First)
129 != NU_SUCCESS)
130 return(OS_ERROR);
131 sprintf(Buffer,
132 "Heapname:%s Addr:%lx Size:%ld Min:%ld Free:%ld Suspend:%d",
133 Name, (UNSIGNED) pStartAddress, Size, Min, Available,
134 SuspendType);
135 return(OS_OK);
136 }
137
138 GLOBAL LONG
139 os_MemInit(void)
140 {
141 USHORT i;
142
143 if (NU_Create_Semaphore(&MemSemCB, "MEMSEM", 1, NU_PRIORITY)
144 != NU_SUCCESS)
145 return(OS_ERROR);
146 for (i = 0; i <= MaxPoolGroups; i++) {
147 PoolBorder[i].Start = (char *)0xFFFFFFFF;
148 PoolBorder[i].End = (char *)0;
149 PartGrpTable[i].grp_head = 0;
150 PartGrpTable[i].name[0] = 0;
151 }
152 MemPoolTable[0].pcb = &mem_pool_head;
153 return(OS_OK);
154 }
155
156 void
157 os_InitPartitionCheck(T_OS_PART_POOL *pool)
158 {
159 unsigned **Buffer, offset;
160 USHORT i, k;
161
162 NU_Allocate_Memory(MemPoolTable[0].pcb, (VOID **) &Buffer,
163 pool->pcb.pm_available * sizeof(unsigned *),
164 NU_NO_SUSPEND);
165 offset = pool->pcb.pm_partition_size / sizeof(unsigned) - 1;
166 for (i = 0; ; i++) {
167 if (NU_Allocate_Partition(&pool->pcb, (VOID **)(Buffer + i),
168 NU_NO_SUSPEND)
169 != NU_SUCCESS)
170 break;
171 Buffer[i][offset] = GUARD_PATTERN;
172 }
173 for (k = 0; k < i; k++)
174 if (NU_Deallocate_Partition(Buffer[k]) != NU_SUCCESS)
175 break;
176 NU_Deallocate_Memory(Buffer);
177 }
178
179 GLOBAL const ULONG *
180 os_GetPrimpoolCB(int grp, int id)
181 {
182 T_OS_PART_POOL *pool;
183 int i;
184
185 pool = PartGrpTable[grp].grp_head;
186 if (!pool)
187 return(0);
188 if (id < 0)
189 return(0);
190 for (i = 0; i < id; i++) {
191 pool = pool->next;
192 if (!pool)
193 return(0);
194 }
195 return (const ULONG *) &pool->pcb;
196 }
197
198 GLOBAL LONG
199 os_GetPartitionPoolStatus(ULONG size, OS_HANDLE gr_hndl,
200 USHORT *m_free, USHORT *m_alloc)
201 {
202 T_OS_PART_POOL *pool;
203 UNSIGNED dummy, allocated, available;
204 CHAR Name[NU_MAX_NAME];
205
206 for (pool = PartGrpTable[gr_hndl].grp_head; pool; pool = pool->next) {
207 if (!size)
208 break;
209 if (size > pool->size)
210 continue;
211 if (NU_Partition_Pool_Information(&pool->pcb, Name,
212 (VOID **)&dummy, &dummy,
213 &dummy, &available,
214 &allocated, (OPTION *)&dummy,
215 &dummy, (NU_TASK **)&dummy)
216 != NU_SUCCESS)
217 break;
218 *m_alloc = allocated;
219 *m_free = available;
220 return(OS_OK);
221 }
222 *m_alloc = 0;
223 *m_free = 0;
224 return(OS_ERROR);
225 }
226
227 GLOBAL LONG
228 os_GetPartitionGroupHandle(OS_HANDLE Caller, char *Name, OS_HANDLE *GroupHandle)
229 {
230 int i;
231
232 for (i = 0; i <= MaxPoolGroups; i++) {
233 if (!PartGrpTable[i].grp_head)
234 continue;
235 if (strncmp(Name, PartGrpTable[i].name, RESOURCE_NAMELEN-1))
236 continue;
237 *GroupHandle = i;
238 return(OS_OK);
239 }
240 return(OS_ERROR);
241 }
242
243 GLOBAL LONG
244 os_DeallocateMemory(OS_HANDLE TaskHandle, T_VOID_STRUCT *Buffer)
245 {
246 if (NU_Deallocate_Memory(Buffer) == NU_SUCCESS)
247 return(OS_OK);
248 else
249 return(OS_ERROR);
250 }
251
252 GLOBAL LONG
253 os_AllocateMemory(OS_HANDLE TaskHandle, T_VOID_STRUCT **Buffer, ULONG Size,
254 ULONG Suspend, OS_HANDLE PoolHandle)
255 {
256 int ret, sts;
257
258 if (Suspend == 0xFFFFFFFF)
259 Suspend = 1;
260 ret = OS_OK;
261 for (;;) {
262 sts = NU_Allocate_Memory(MemPoolTable[PoolHandle].pcb, Buffer,
263 Size, Suspend);
264 switch (sts) {
265 case NU_SUCCESS:
266 return(ret);
267 case NU_INVALID_SUSPEND:
268 Suspend = 0;
269 continue;
270 case NU_NO_MEMORY:
271 case NU_TIMEOUT:
272 if (Suspend == 1) {
273 Suspend = 0xFFFFFFFF;
274 ret = OS_WAITED;
275 continue;
276 } else {
277 *Buffer = 0;
278 return(OS_TIMEOUT);
279 }
280 default:
281 /*
282 * Disassembly reveals that the original code
283 * has an endless loop here, the equivalent
284 * of continue. My guess is that they simply
285 * forgot the default case, and so control
286 * falls onto the closing brace of the switch
287 * and then onto the closing brace of the for
288 * loop. But I prefer better error handling,
289 * hence the present addition. - Space Falcon
290 */
291 *Buffer = 0;
292 return(OS_ERROR);
293 }
294 }
295 }
296
297 GLOBAL LONG
298 os_CreatePartitionPool(OS_HANDLE TaskHandle, char *GroupName, void *Addr,
299 USHORT Num, ULONG Size, OS_HANDLE *GroupHandle)
300 {
301 STATUS sts;
302 T_OS_PART_POOL *part_group_head, *opool, *npool;
303 USHORT part_group;
304 USHORT i, j;
305 char PoolName[8], *cp;
306
307 sts = NU_Obtain_Semaphore(&MemSemCB, NU_SUSPEND);
308 j = 0;
309 part_group_head = 0;
310 for (i = 0; i <= MaxPoolGroups; i++) {
311 if (!PartGrpTable[i].grp_head || !PartGrpTable[i].name[0])
312 break;
313 if (!strncmp(GroupName, PartGrpTable[i].name,
314 RESOURCE_NAMELEN - 1)) {
315 part_group_head = PartGrpTable[i].grp_head;
316 opool = part_group_head;
317 j++;
318 while (opool->next) {
319 opool = opool->next;
320 j++;
321 }
322 break;
323 }
324 }
325 /*
326 * This error check logic has been modified from the original
327 * faithful reconstruction by Space Falcon. In the original code
328 * if MaxPoolGroups had been reached and the for loop above
329 * never broke, the code would proceed to overwrite pool #0
330 * instead of catching the error.
331 */
332 if (i > MaxPoolGroups) {
333 release_sem_return_err:
334 if (sts == NU_SUCCESS)
335 NU_Release_Semaphore(&MemSemCB);
336 return(OS_ERROR);
337 }
338 part_group = i;
339 if (!part_group_head) {
340 strncpy(PartGrpTable[part_group].name, GroupName,
341 RESOURCE_NAMELEN);
342 PartGrpTable[part_group].name[RESOURCE_NAMELEN-1] = 0;
343 }
344 if (os_AllocateMemory(OS_NOTASK, (T_VOID_STRUCT **) &npool,
345 sizeof(T_OS_PART_POOL), OS_NO_SUSPEND,
346 os_ext_pool_handle) != OS_OK)
347 goto release_sem_return_err;
348 sprintf(PoolName, "POOL%1d%1d", part_group + 1, j);
349 Size &= ~3;
350 npool->pool_mem = Addr;
351 /*
352 * FreeCalypso: we need to bzero the PM_PCB before calling
353 * NU_Create_Partition_Pool() to prevent the possibility of
354 * Nucleus error checker failing the call because the
355 * signature word happens to be there already.
356 */
357 bzero(&npool->pcb, sizeof(NU_PARTITION_POOL));
358 if (NU_Create_Partition_Pool(&npool->pcb, PoolName, npool->pool_mem,
359 POOL_SIZE(Num, Size), Size + 4, NU_FIFO)
360 != NU_SUCCESS)
361 goto release_sem_return_err;
362 if (!part_group_head)
363 PartGrpTable[part_group].grp_head = npool;
364 else
365 opool->next = npool;
366 npool->size = Size;
367 npool->next = 0;
368 *GroupHandle = part_group;
369 cp = (char *) npool->pool_mem;
370 if (PoolBorder[part_group].Start >= cp)
371 PoolBorder[part_group].Start = cp;
372 cp += POOL_SIZE(Num, Size);
373 if (PoolBorder[part_group].End < cp)
374 PoolBorder[part_group].End = cp;
375 os_InitPartitionCheck(npool);
376 if (sts == NU_SUCCESS)
377 NU_Release_Semaphore(&MemSemCB);
378 return(OS_OK);
379 }
380
381 GLOBAL LONG
382 os_CreatePartitionPool_fixed_pool_size(OS_HANDLE TaskHandle, char *GroupName,
383 void *Addr, USHORT PoolSize,
384 ULONG PartSize, OS_HANDLE *GroupHandle,
385 ULONG *NumCreated)
386 {
387 USHORT num;
388
389 num = PoolSize / (PartSize + PT_CHKOVERHEAD + PT_OVERHEAD);
390 *NumCreated = num;
391 return os_CreatePartitionPool(TaskHandle, GroupName, Addr, num,
392 PartSize, GroupHandle);
393 }
394
395 GLOBAL LONG
396 os_CreateMemoryPool(OS_HANDLE TaskHandle, char *Name, void *Addr,
397 ULONG PoolSize, OS_HANDLE *PoolHandle)
398 {
399 STATUS sts;
400 USHORT i;
401
402 sts = NU_Obtain_Semaphore(&MemSemCB, NU_SUSPEND);
403 for (i = 0; i < NumOfMemoryPools; i++)
404 if (!strncmp(Name, MemPoolTable[i].name, RESOURCE_NAMELEN-1)) {
405 *PoolHandle = i;
406 if (sts == NU_SUCCESS)
407 NU_Release_Semaphore(&MemSemCB);
408 return(OS_OK);
409 }
410 if (i >= MaxMemoryPools) {
411 release_sem_return_err:
412 if (sts == NU_SUCCESS)
413 NU_Release_Semaphore(&MemSemCB);
414 return(OS_ERROR);
415 }
416 if (i) {
417 if (os_AllocateMemory(OS_NOTASK,
418 (T_VOID_STRUCT **) &MemPoolTable[i].pcb,
419 sizeof(NU_MEMORY_POOL), OS_NO_SUSPEND,
420 os_ext_pool_handle) != OS_OK)
421 goto release_sem_return_err;
422 /*
423 * FreeCalypso: we need to bzero the DM_PCB before calling
424 * NU_Create_Memory_Pool() to prevent the possibility of
425 * Nucleus error checker failing the call because the
426 * signature word happens to be there already.
427 */
428 bzero(MemPoolTable[i].pcb, sizeof(NU_MEMORY_POOL));
429 }
430 if (NU_Create_Memory_Pool(MemPoolTable[i].pcb, Name, Addr, PoolSize,
431 4, NU_FIFO) != NU_SUCCESS)
432 goto release_sem_return_err;
433 strncpy(MemPoolTable[i].name, Name, RESOURCE_NAMELEN);
434 MemPoolTable[i].name[RESOURCE_NAMELEN-1] = 0;
435 *PoolHandle = i;
436 NumOfMemoryPools++;
437 if (sts == NU_SUCCESS)
438 NU_Release_Semaphore(&MemSemCB);
439 return(OS_OK);
440 }