diff --git a/core/mem.c b/core/mem.c index 09712a0..19bea4a 100644 --- a/core/mem.c +++ b/core/mem.c @@ -8,10 +8,10 @@ static struct mem_desc *used_page; static unsigned long bottom_mem; static unsigned long top_mem; - int memSetup(unsigned long upper_mem) { - printf("Free Mem going from %d to %d\n", &__ld_kernel_end, upper_mem * 1024); + printf("Free Mem from %d to %d\n", &__ld_kernel_end, upper_mem * 1024); + // Memory description is stored after the kernel. We need some place to store it unsigned long memdesc_end = (unsigned long)page_desc + ((upper_mem) / (PAGE_SIZE / 1024)) * sizeof(struct mem_desc); @@ -19,7 +19,7 @@ int memSetup(unsigned long upper_mem) list_init(free_page); list_init(used_page); bottom_mem = lastUsed; - top_mem = upper_mem; + top_mem = upper_mem * 1024; for (uint i = 0; i < (upper_mem / (PAGE_SIZE / 1024)); i++) { struct mem_desc *mem = &page_desc[i]; if (i < lastUsed) { @@ -38,15 +38,16 @@ struct mem_desc *addr2memDesc(unsigned long addr) { if (addr > top_mem || addr < bottom_mem) return NULL; + int idx = addr >> PAGE_SHIFT; return page_desc + idx; } - unsigned long allocPage(void) { - if (list_is_empty(free_page)) + if (list_is_empty(free_page)) { return (unsigned long)NULL; + } struct mem_desc *mem = list_pop_head(free_page); mem->ref = 1; list_add_tail(used_page, mem); @@ -61,6 +62,7 @@ int unrefPage(unsigned long addr) } mem->ref--; if (mem->ref == 0) { + list_delete(used_page, mem); list_add_tail(free_page, mem); } diff --git a/tests/test.c b/tests/test.c index 4fad5e4..c1271bf 100644 --- a/tests/test.c +++ b/tests/test.c @@ -1,7 +1,46 @@ +#include "list.h" +#include "mem.h" #include "serial.h" #include "vga.h" -void run_test(){ +static void testPhymem() +{ + printf("Testing memory PHY\n"); + struct mem_desc *allocated_page_list; + struct mem_desc + *page; // Cast in mem_desc to use it. In fact it's the addr of 4K free memory + list_init(allocated_page_list); + int allocCount = 0; + int freeCount = 0; + + while ((page = (struct mem_desc *)allocPage()) != NULL) { + page->phy_addr = allocCount; + allocCount++; + list_add_tail(allocated_page_list, page); + } + printf("%d pages allocated\n", allocCount); + + while ((page = list_pop_head(allocated_page_list)) != NULL) { + if (page->phy_addr != (ulong)freeCount) { + printf("Error page %d modified\n", (ulong)page); + } + if (unrefPage((ulong)page)) { + printf("Failed to free page %d\n", (ulong)page); + } + freeCount++; + } + printf("%d pages freed\n", freeCount); + + if ((page = (struct mem_desc *)allocPage()) == NULL) { + printf("Error ! Cannot allocate memory\n"); + } else { + unrefPage((ulong)page); + } +} + +void run_test() +{ + testPhymem(); printf("Testing Serial"); serialWrite('h'); serialWrite('e');