summaryrefslogtreecommitdiffstats
path: root/boot/limine/memorymap.c
blob: 48f3f3368677f47fb53806e248562762c2d6b31d (plain) (blame)
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include "hal/obj.h"
#include "jove.h"
#include "limine.h"
#include "hal/memory.h"
#include "hal/obj.h"
#include "panic/panic.h"
#include "proc/init.h"
#include "lib/printf.h"

extern struct limine_memmap_response *_limine_memmap_resp;

PAGEALIGN
static jove_objdir_t s_region_objdir;
static jove_objdir_t s_hwmemory_objdir;

#define MEMMAP_MAX_ENTRIES 255

static const char *limine_mmap_entry_type_str[9] = {
    "USABLE",
    "RESERVED",
    "ACPI RECLAIMABLE",
    "ACPI NVS",
    "BAD",
    "LIMINE RECLAIMABLE",
    "KERNEL",
    "FRAMEBUFFER",
    "ACPI TABLES"
};

void
mem_setup_regions(void)
{
    {
        jove_owned_obj_t *region_objdir_obj = objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_FREEMEMORY_I);
        obj_settype(region_objdir_obj, JOVE_OBJ_OBJDIR);
        obj_setvalue(region_objdir_obj, (uintptr_t)&s_region_objdir);
        obj_release(region_objdir_obj);
    }

    if(_limine_memmap_resp == NULL) {
        kpanic("Limine failed to provide memory map.\n");
    }

    kprintf("Memory map provided by Limine:\n");

    size_t region_i = 0;
    size_t hwmem_i = 0;

    for(size_t i = 0; i < _limine_memmap_resp->entry_count; i++) {
        struct limine_memmap_entry *entry = _limine_memmap_resp->entries[i];

        if(entry->type == LIMINE_MEMMAP_USABLE ||
           entry->type == LIMINE_MEMMAP_ACPI_RECLAIMABLE ||
           entry->type == LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE)
        {
            if(region_i > JOVE_OBJDIR_ENTRIES){
                kprintf("%s: Provided memory map exceeds kernel limits. Some memory may not be accessable.", __func__);
                break;
            }
 
            klogf("%p : %p %s\n", entry->base, entry->length, limine_mmap_entry_type_str[entry->type]);
            if(entry->base == 0) continue;

            {
                jove_owned_obj_t *region_obj = obj_take(&s_region_objdir.entries[region_i++]);
                region_new(region_obj, entry->base, entry->length / 0x1000);
                obj_release(region_obj);
            }
        }
        if(entry->type == LIMINE_MEMMAP_RESERVED |
            entry->type == LIMINE_MEMMAP_ACPI_NVS |
            entry->type == LIMINE_MEMMAP_ACPI_TABLES)
        {
            intmax_t hw_pages = entry->length >> 12;
            uintptr_t base = entry->base;
            while(hw_pages > 0) {
                if(hwmem_i >= JOVE_OBJDIR_ENTRIES) {
                    kprintf("%s: Reserved memory region exceeds indexing limits!\n", __func__);
                    break;
                }

                size_t pages = hw_pages > 4095 ? 4095 : hw_pages;
                //klogf("%p : %p RESERVED\n", base, ((pages + 1) << 12));

                jove_owned_obj_t *hwmem_obj = obj_take(&s_hwmemory_objdir.entries[hwmem_i++]);
                obj_settype(hwmem_obj, JOVE_OBJ_SHMEMORY);
                obj_setvalue(hwmem_obj, entry->base | (entry->length >> 12));

                obj_release(hwmem_obj);
                hw_pages -= 4096;
                base += (4096ULL << 12);
            }
        }
    }
}