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);
31static sysmem_alloc_element_t *search_block(
void *a1);
35 int (*cbCpuSuspendIntr)(
int *state);
36 int (*cbCpuResumeIntr)(
int state);
38 int (*cbQueryIntrContext)(void);
41int _start(
unsigned int memsize)
43 if ( memsize > 0x7FFF00 )
45 sysmem_internals.alloclist = (sysmem_alloc_table_t *)0x401100;
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)
58 sysmem_alloc_table_t *alloclist;
59 sysmem_alloc_table_t *v1;
62 sysmem_alloc_table_t *v4;
63 sysmem_alloc_element_t *v5;
66 const sysmem_alloc_table_t *v8;
67 const sysmem_alloc_element_t *list;
70 alloclist = sysmem_internals.alloclist;
71 if ( !sysmem_internals.alloclist )
73 v1 = sysmem_internals.alloclist;
74 sysmem_internals.alloclist->next = 0;
80 v5 = (sysmem_alloc_element_t *)((
char *)v1 + v3);
82 v4->list[0].next = v5;
85 v4 = (sysmem_alloc_table_t *)((
char *)v4 + 8);
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()
129 const sysmem_alloc_element_t *list;
133 if ( !sysmem_internals.alloclist )
135 cCpuSuspendIntr(&state);
136 list = sysmem_internals.alloclist->list;
137 if ( sysmem_internals.alloclist != (sysmem_alloc_table_t *)-4 )
141 if ( (list->info & 1) == 0 && v0 < list->info >> 17 )
142 v0 = list->info >> 17;
146 cCpuResumeIntr(state);
150u32 QueryTotalFreeMemSize()
153 const sysmem_alloc_element_t *list;
157 if ( !sysmem_internals.alloclist )
159 cCpuSuspendIntr(&state);
160 list = sysmem_internals.alloclist->list;
161 if ( sysmem_internals.alloclist != (sysmem_alloc_table_t *)-4 )
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)
193 const sysmem_alloc_table_t *alloclist;
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)
217 const sysmem_alloc_element_t *v3;
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)
240 const sysmem_alloc_element_t *v3;
244 cCpuSuspendIntr(&state);
245 v3 = search_block(address);
251 v2 = info >> 17 << 8;
252 if ( (info & 1) == 0 )
255 cCpuResumeIntr(state);
259void GetSysMemoryInfo(
int flag, sysmem_info_t *info)
261 sysmem_alloc_table_t *table_info;
263 sysmem_alloc_table_t *v6;
265 const sysmem_alloc_table_t *alloclist;
266 sysmem_alloc_table_t *next;
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;
275 info->meminfo.memlist_first = (sysmem_alloc_table_t *)sysmem_internals.alloclist->list;
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)
332 sysmem_alloc_element_t *i;
335 sysmem_alloc_element_t *list;
336 sysmem_alloc_element_t *v9;
338 sysmem_alloc_element_t *next;
348 sysmem_alloc_element_t *v25;
349 sysmem_alloc_element_t *v26;
358 v3 = (
unsigned int)(size + 255) >> 8;
364 list = sysmem_internals.alloclist->list;
366 if ( sysmem_internals.alloclist != (sysmem_alloc_table_t *)-4 )
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;
501 if ( sysmem_internals.alloclist != (sysmem_alloc_table_t *)-4 )
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)
549 sysmem_alloc_element_t *v4;
550 sysmem_alloc_element_t *v5;
553 sysmem_alloc_element_t *v9;
554 const sysmem_alloc_element_t *next;
556 const sysmem_alloc_element_t *i;
558 v2 = (
unsigned int)ptr >> 8;
559 if ( (((uiptr)ptr) & 0xFF) != 0 )
561 v4 = &sysmem_internals.alloclist->list[2];
563 if ( sysmem_internals.alloclist == (sysmem_alloc_table_t *)-20 )
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)
623 sysmem_alloc_table_t *alloclist;
624 sysmem_alloc_table_t *next;
625 sysmem_alloc_element_t *v6;
626 sysmem_alloc_table_t *v7;
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);
641 alloclist->next = (sysmem_alloc_table_t *)v1;
646 sysmem_alloc_table_t *v5;
649 alloclist->list[30].next = (sysmem_alloc_element_t *)(v1 + 4);
650 next = alloclist->next;
656 v6 = (sysmem_alloc_element_t *)((
char *)next + v4);
658 v5->list[0].next = v6;
659 v5->list[0].info = 0;
661 v5 = (sysmem_alloc_table_t *)((
char *)v5 + 8);
662 }
while ( v2 < 0x1F );
663 next->list[30].next = 0;
666 v7 = sysmem_internals.alloclist;
667 if ( sysmem_internals.alloclist->next )
669 sysmem_alloc_table_t *v8;
671 while ( v7->next->next )
676 if ( !(v7->list[27].info >> 17) )
678 v7->list[30].next = 0;
680 freeSysMemory_internal(v8);
686static sysmem_alloc_element_t *search_block(
void *a1)
688 sysmem_alloc_element_t *list;
690 list = sysmem_internals.alloclist->list;
691 if ( sysmem_internals.alloclist != (sysmem_alloc_table_t *)-4 )
700 if ( (
unsigned int)a1 >= (
unsigned int)(v3 << 8) && (
unsigned int)a1 < (v3 + (info >> 17)) << 8 )
708static int cCpuSuspendIntr(
int *state)
710 intrman_callbacks_t *intrman_callbacks = (intrman_callbacks_t *)(sysmem_internals.intr_suspend_tbl);
711 if ( intrman_callbacks && intrman_callbacks->cbCpuSuspendIntr )
712 return intrman_callbacks->cbCpuSuspendIntr(state);
717static int cCpuResumeIntr(
int state)
719 intrman_callbacks_t *intrman_callbacks = (intrman_callbacks_t *)(sysmem_internals.intr_suspend_tbl);
720 if ( intrman_callbacks && intrman_callbacks->cbCpuResumeIntr )
721 return intrman_callbacks->cbCpuResumeIntr(state);
727static int cQueryIntrContext(
void)
729 intrman_callbacks_t *intrman_callbacks = (intrman_callbacks_t *)(sysmem_internals.intr_suspend_tbl);
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;
struct sysmem_internals_ sysmem_internals_t