#include #include #include #include #include #include size_t mem_used = 0; size_t mem_total = 0; struct List mem_blocks = {0}; static struct MemBlock *mem_base = (struct MemBlock *)0x100000; static uintptr_t bumppos = 0x1000000; void MemInit(void) { NewList(&mem_blocks, LP_BLOCK); } struct MemBlock *MarkMem(uintptr_t base, size_t limit, uint8_t flags) { /* DOESN'T WORK. BROKEN. */ struct MemBlock *block = (struct MemBlock *)(base-sizeof(struct MemBlock)); struct MemBlock *lastblock = (struct MemBlock *)mem_blocks.head; block->size = limit; block->flags = flags; /* find where to insert block */ while (lastblock->node.next) { if (lastblock->node.next == &mem_blocks.tail) { /* at last block */ break; } if ((uintptr_t)lastblock->node.next + sizeof(struct MemBlock) >= base) { /* next block is past base */ break; } lastblock = (struct MemBlock *)lastblock->node.next; } Insert(&mem_blocks, (struct Node *)block, (struct Node *)lastblock); size_t deltaprev = (uintptr_t)block - (uintptr_t)lastblock - sizeof(struct MemBlock); size_t deltanext = lastblock->size - deltaprev - limit; if (deltaprev < lastblock->size) { lastblock->size = deltaprev; if (deltanext > 0) { struct MemBlock *nextblock = (struct MemBlock *)((uintptr_t)block + sizeof(struct MemBlock) + limit); nextblock->size = deltanext; nextblock->flags = lastblock->flags; } } return block; } void *AllocMemEx(size_t size, uint8_t flags) { #if 0 struct MemBlock *block = (struct MemBlock *)&mem_blocks.head; while (block->node.next) { block = (struct MemBlock *)block->node.next; if ((block->flags & 3) == MF_FREE && (block->size >= size)) { size_t remaining = block->size - size; block->flags &= MF_USED; block->size = size; mem_used += size; if (remaining > sizeof(struct MemBlock)) { struct MemBlock *newblock = (struct MemBlock *)((uintptr_t)block + sizeof(struct MemBlock) + size); newblock->size = remaining - sizeof(struct MemBlock); newblock->flags = MF_FREE; Insert(&mem_blocks, (struct Node *)block, (struct Node *)newblock); } return (void *)((uintptr_t)block + sizeof(struct MemBlock)); } } #endif /* temporary bump allocator */ void *addr = (void *)bumppos; bumppos += size; return addr; } void *AllocMem(size_t size) { return AllocMemEx(size, 0); } void FreeMemEx(void *block, size_t size) { } void FreeMem(void *block) { FreeMemEx(block, 0); } void PrintMem(void) { struct MemBlock *block = (struct MemBlock *)&mem_blocks.head; while (block->node.next) { block = (struct MemBlock *)block->node.next; DebconPrint("Block at "); DebconPrintHex((uintptr_t)block); DebconPrint(": size "); DebconPrintHex(block->size); DebconPrint(", flags "); DebconPrintHex(block->flags); DebconPrint(", next "); DebconPrintHex((uint32_t)block->node.next); DebconPrint("\n"); if (block->node.next == &block->node) { DebconPrint("Loop detected!\n"); break; } } }