17IRX_ID(
"System_Memory_Manager", 2, 3);
22static KprintfHandler_t *kprintf_cb;
23static void *kprintf_cb_userdata;
25extern int sysmem_reinit(
void);
26static int cCpuSuspendIntr(
int *state);
27static int cCpuResumeIntr(
int state);
28static int allocSysMemory_internal(
int flags,
int size,
void *mem);
29static int freeSysMemory_internal(
void *ptr);
30static void updateSmemCtlBlk(
void);
35 int (*cbCpuSuspendIntr)(
int *state);
36 int (*cbCpuResumeIntr)(
int state);
38 int (*cbQueryIntrContext)(void);
41int _start(
unsigned int memsize)
43 if ( memsize > 0x7FFF00 )
46 sysmem_internals.memsize = memsize & 0xFFFFFF00;
47 sysmem_internals.intr_suspend_tbl = 0;
48 sysmem_internals.allocation_count = 0;
49 sysmem_internals.smemupdate_cur = 0;
50 if ( (memsize & 0xFFFFFF00) >= 0x401200 )
51 return sysmem_reinit();
52 sysmem_internals.alloclist = 0;
56int sysmem_reinit(
void)
70 alloclist = sysmem_internals.alloclist;
71 if ( !sysmem_internals.alloclist )
73 v1 = sysmem_internals.alloclist;
74 sysmem_internals.alloclist->next = 0;
82 v4->list[0].next = v5;
87 memsize = sysmem_internals.memsize;
88 info = v1->list[0].info;
89 v1->list[30].next = 0;
90 v1->list[0].info = (
info & 0x1FFFF) | ((memsize / 256) << 17);
91 sysmem_internals.allocation_count = 1;
93 AllocSysMemory(0, (
int)sysmem_internals.alloclist, 0)
94 || (v8 = (
sysmem_alloc_table_t *)AllocSysMemory(0, 0xFC, 0), list = v8->list, v8 != sysmem_internals.alloclist) )
96 sysmem_internals.alloclist = 0;
107 if ( (v11 & 1) == 0 )
113 return (u16)v11 >> 1 << 8;
120 if ( sysmem_internals.alloclist )
121 return sysmem_internals.memsize;
126u32 QueryMaxFreeMemSize()
133 if ( !sysmem_internals.alloclist )
135 cCpuSuspendIntr(&state);
136 list = sysmem_internals.alloclist->list;
141 if ( (list->info & 1) == 0 && v0 < list->
info >> 17 )
142 v0 = list->info >> 17;
146 cCpuResumeIntr(state);
150u32 QueryTotalFreeMemSize()
157 if ( !sysmem_internals.alloclist )
159 cCpuSuspendIntr(&state);
160 list = sysmem_internals.alloclist->list;
168 if ( (
info & 1) == 0 )
173 cCpuResumeIntr(state);
177void *AllocSysMemory(
int mode,
int size,
void *ptr)
182 if ( !sysmem_internals.alloclist || (
unsigned int)mode >= 3 )
184 cCpuSuspendIntr(&state);
185 v6 = (
void *)allocSysMemory_internal(mode, size, ptr);
187 cCpuResumeIntr(state);
191int FreeSysMemory(
void *ptr)
197 alloclist = sysmem_internals.alloclist;
198 while ( alloclist && ptr != alloclist )
200 alloclist = alloclist->next;
206 cCpuSuspendIntr(&state);
207 v4 = freeSysMemory_internal(ptr);
210 cCpuResumeIntr(state);
214void *QueryBlockTopAddress(
void *address)
221 cCpuSuspendIntr(&state);
222 v3 = search_block(address);
228 if ( (
info & 1) != 0 )
229 v2 = (u16)
info >> 1 << 8;
231 v2 = ((u16)
info >> 1 << 8) + 0x80000000;
233 cCpuResumeIntr(state);
237int QueryBlockSize(
void *address)
244 cCpuSuspendIntr(&state);
245 v3 = search_block(address);
251 v2 =
info >> 17 << 8;
252 if ( (
info & 1) == 0 )
255 cCpuResumeIntr(state);
269 cCpuSuspendIntr(&state);
272 info->meminfo.allocation_count = sysmem_internals.allocation_count;
273 info->meminfo.memsize = sysmem_internals.memsize;
274 info->meminfo.memlist_last = sysmem_internals.smemupdate_cur;
276 cCpuResumeIntr(state);
279 if (
info->meminfo.memlist_last != sysmem_internals.smemupdate_cur )
281 info->blockinfo.block_address = (
void *)-1;
282 info->blockinfo.flags_memsize = -1;
283 info->blockinfo.table_info = 0;
284 cCpuResumeIntr(state);
287 table_info =
info->blockinfo.table_info;
290 memsize = (
void *)sysmem_internals.memsize;
291 info->blockinfo.flags_memsize = 1;
292 info->blockinfo.block_address = memsize;
293 cCpuResumeIntr(state);
296 v6 =
info->blockinfo.table_info;
297 info->blockinfo.block_address = (
void *)((((
unsigned int)table_info->list[0].next >> 1) & 0x7FFF) << 8);
298 v7 = (
unsigned int)v6->list[0].next >> 17 << 8;
299 info->blockinfo.flags_memsize = v7;
300 if ( ((
int)v6->list[0].next & 1) != 0 )
302 alloclist = sysmem_internals.alloclist;
303 while ( alloclist && alloclist !=
info->blockinfo.block_address )
305 alloclist = alloclist->next;
309 info->blockinfo.flags_memsize |= 2u;
314 info->blockinfo.flags_memsize |= 1;
316 next =
info->blockinfo.table_info->next;
317 info->blockinfo.table_info = next;
318 if ( !((
unsigned int)next->list[0].next >> 17) )
319 info->blockinfo.table_info = 0;
320 cCpuResumeIntr(state);
325 return &sysmem_internals;
328static int allocSysMemory_internal(
int flags,
int size,
void *mem)
358 v3 = (
unsigned int)(size + 255) >> 8;
364 list = sysmem_internals.alloclist->list;
373 if ( (
info & 1) == 0 &&
info >> 17 >= v3 )
383 if ( v7 >> 17 != v3 )
389 ++sysmem_internals.allocation_count;
390 v11 = (v9->info & 0x1FFFF) | (((v9->info >> 17) - v3) << 17);
391 v12 = (v11 >> 1) & 0x7FFF;
394 v13 = (v31 & 0x10001) | (u16)(2 * ((v12 + v11) & 0x7FFF)) | (v3 << 17) | 1;
395 v14 = (u16)((((u8 *)&v31)[0] & 1) | (2 * ((v12 + v11) & 0x7FFF)) | 1) >> 1;
409 }
while ( v36 >> 17 );
414 return (((v7 | 1) >> 1) & 0x7FFF) << 8;
417 else if ( flags >= 2 )
423 if ( (((uiptr)mem) & 0xFF) == 0 )
425 v17 = (
unsigned int)mem >> 8;
426 for ( i = sysmem_internals.alloclist->list;; i = i->next )
436 if ( (v18 & 1) == 0 && v19 + (v18 >> 17) >= ((
unsigned int)mem >> 8) + v3 )
438 if ( ((i->info >> 1) & 0x7FFF) < v17 )
440 ++sysmem_internals.allocation_count;
445 v23 = v22 + v20 - v17;
446 v24 = v21 | ((v20 - v23) << 17);
448 v32 = (u16)(2 * ((((v24 >> 1) & 0x7FFF) + (v24 >> 17)) & 0x7FFF)) | (v23 << 17);
459 }
while ( v35 >> 17 );
464 if ( v7 >> 17 != v3 )
466 ++sysmem_internals.allocation_count;
468 i->info = (v27 & 0x1FFFE) | 1 | (v3 << 17);
469 v28 = 2 * ((((v27 >> 1) & 0x7FFF) + (u16)v3) & 0x7FFF);
470 v31 = (v27 & 0x10001) | (v28 & 0x1FFFF) | (((((v27 & 0xFFFF0001) | v28) >> 17) - v3) << 17);
472 v16 = (u16)v27 >> 1 << 8;
483 }
while ( v36 >> 17 );
488 return (((v7 | 1) >> 1) & 0x7FFF) << 8;
499 i = sysmem_internals.alloclist->list;
506 if ( (v6 & 1) == 0 && v6 >> 17 >= v3 )
514 if ( v7 >> 17 != v3 )
516 ++sysmem_internals.allocation_count;
518 i->info = (v27 & 0x1FFFE) | 1 | (v3 << 17);
519 v28 = 2 * ((((v27 >> 1) & 0x7FFF) + (u16)v3) & 0x7FFF);
520 v31 = (v27 & 0x10001) | (v28 & 0x1FFFF) | (((((v27 & 0xFFFF0001) | v28) >> 17) - v3) << 17);
522 v16 = (u16)v27 >> 1 << 8;
533 }
while ( v36 >> 17 );
538 return (((v7 | 1) >> 1) & 0x7FFF) << 8;
546static int freeSysMemory_internal(
void *ptr)
558 v2 = (
unsigned int)ptr >> 8;
559 if ( (((uiptr)ptr) & 0xFF) != 0 )
561 v4 = &sysmem_internals.alloclist->list[2];
570 if (
info >> 17 && (u16)
info >> 1 == v2 )
583 v4->info = v7 & 0xFFFFFFFE;
591 if ( (v11 & 1) == 0 )
594 --sysmem_internals.allocation_count;
596 v4->info = (v4->info & 0x1FFFF) | (((v4->info >> 17) + (v4->next->info >> 17)) << 17);
600 if ( v5 && (v5->info & 1) == 0 )
604 --sysmem_internals.allocation_count;
605 v5->info = (v5->info & 0x1FFFF) | (((v5->info >> 17) + (v4->info >> 17)) << 17);
610 for ( i = v9; v12 != -1; --v12 )
621static void updateSmemCtlBlk(
void)
628 alloclist = sysmem_internals.alloclist;
629 ++sysmem_internals.smemupdate_cur;
630 if ( sysmem_internals.alloclist->next )
633 alloclist = alloclist->next;
634 while ( alloclist->next );
636 if ( alloclist->list[27].info >> 17 )
640 v1 = allocSysMemory_internal(0, 256, 0);
650 next = alloclist->next;
658 v5->list[0].next = v6;
659 v5->list[0].info = 0;
662 }
while ( v2 < 0x1F );
663 next->list[30].next = 0;
666 v7 = sysmem_internals.alloclist;
667 if ( sysmem_internals.alloclist->next )
671 while ( v7->next->next )
676 if ( !(v7->list[27].info >> 17) )
678 v7->list[30].next = 0;
680 freeSysMemory_internal(v8);
690 list = sysmem_internals.alloclist->list;
700 if ( (
unsigned int)a1 >= (
unsigned int)(v3 << 8) && (
unsigned int)a1 < (v3 + (
info >> 17)) << 8 )
708static int cCpuSuspendIntr(
int *state)
711 if ( intrman_callbacks && intrman_callbacks->cbCpuSuspendIntr )
712 return intrman_callbacks->cbCpuSuspendIntr(state);
717static int cCpuResumeIntr(
int state)
720 if ( intrman_callbacks && intrman_callbacks->cbCpuResumeIntr )
721 return intrman_callbacks->cbCpuResumeIntr(state);
727static int cQueryIntrContext(
void)
730 if ( intrman_callbacks && intrman_callbacks->cbQueryIntrContext )
731 return intrman_callbacks->cbQueryIntrContext();
737int Kprintf(
const char *format, ...)
744 va_start(va, format);
745 ret = kprintf_cb(kprintf_cb_userdata, format, va);
752void KprintfSet(KprintfHandler_t *new_cb,
void *context)
754 if ( kprintf_cb && new_cb )
756 new_cb(context, (
const char *)Kprintf(NULL), NULL);
759 kprintf_cb_userdata = context;