summaryrefslogtreecommitdiff
path: root/arch/i386/kernel/kmalloc.c
blob: 183545ae08103f6ed35b722f3295160fdde8304d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <kernel/kmalloc.h>
#include <kernel/paging.h>
#include <kernel/pmem.h>
#include <kernel/asm.h>
#include <kernel/errno.h>
#include <kernel/panic.h>
#include <stdint.h>

static uintptr_t heap_start = KEND + 0xC0001000;
static uintptr_t heap_end = 0xFFFFF000;

static void *kbrk = NULL;
static struct mem_block *first = NULL;

void _request_page(void) {
        uintptr_t paddr = pfa_alloc();
        if (paddr == PFA_ALLOC_ERR)
                panic("Out of physical memory");

        uintptr_t vaddr = PGROUNDDN((uintptr_t)kbrk + PAGE_SIZE);
        kbrk += PAGE_SIZE;
        map_page(NULL, paddr, vaddr, PD_PRES | PD_RW);
}

void kmalloc_init(void) {
        kbrk = (void*)(heap_start & 0xFFFFF000);
        _request_page();
        first = (struct mem_block*)kbrk;
        first->start = (uintptr_t)kbrk + sizeof(struct mem_block);
        first->size = 0;
        first->alloc = 1;
        first->next = NULL;
}

void* kmalloc(size_t sz) {
        if (kbrk == NULL)
                panic("Attmpted to malloc before initialization");
        if ((uintptr_t)kbrk >= heap_end)
                return NULL;

        struct mem_block *temp = first;
        while (temp->next != NULL) {
                if (temp->size <= sz && temp->alloc == 0)
                        return (void*)temp->start;
                temp = temp->next;
        }

        temp->next = (struct mem_block*)((uintptr_t)temp + sizeof(struct mem_block) + temp->size);
        temp = temp->next;
        temp->start = (uintptr_t)(temp + sizeof(struct mem_block));
        temp->size = sz;
        temp->alloc = 1;
        temp->next = NULL;
        return (void*)temp->start;
}

void kfree(void *ptr) {
        struct mem_block *temp = first;
        while (temp->next != NULL) {
                if (temp->start == (uintptr_t)ptr) {
                        temp->alloc = 0;
                        return;
                }
        }
        panic("Attempted to free memory not alloc'd");
}