summaryrefslogtreecommitdiffstats
path: root/boot/limine/memorymap.c
blob: 98405fda9f4ed843b842da4222894051205e9800 (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
96
97
98
99
100
101
#include "hal/obj.h"
#include "jove.h"
#include "limine.h"
#include "hal/memory.h"
#include "hal/obj.h"
#include "lib/panic.h"
#include "init.h"
#include "lib/printf.h"

extern struct limine_memmap_response *_limine_memmap_resp;

PAGEALIGN
static jove_objdir_t s_untyped_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_untyped(void)
{
    {
        jove_owned_obj_t *untyped_objdir_obj = objdir_getlocal(_rootdir_obj, ROOTDIR_UNTYPED_I);
        obj_settype(untyped_objdir_obj, JOVE_OBJ_OBJDIR);
        obj_setvalue(untyped_objdir_obj, (uintptr_t)&s_untyped_objdir);
        obj_release(untyped_objdir_obj);
    }

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

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

    size_t untyped_i = 0;
    size_t hwmem_i = 0;

    uintptr_t highest_phys = 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(untyped_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;
            if(entry->base + entry->length > highest_phys) highest_phys = entry->base + entry->length;

            {
                jove_owned_obj_t *untyped_obj = obj_take(&s_untyped_objdir.entries[untyped_i++]);
                obj_settype(untyped_obj, JOVE_OBJ_UNTYPED);
                obj_setvalue(untyped_obj, entry->base);

                jove_untyped_t *untyped_data = obj_deref(untyped_obj);
                untyped_data->limit = entry->length;
                obj_release(untyped_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);
            }
        }
    }
}