FreeCalypso > hg > freecalypso-citrine
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 } |