A Total Overhaul on the Lunaix's Virtual Memory Model (#26)
[lunaix-os.git] / lunaix-os / kernel / boot_helper.c
1 #include <klibc/string.h>
2 #include <lunaix/boot_generic.h>
3 #include <lunaix/mm/pmm.h>
4 #include <lunaix/mm/vmm.h>
5 #include <lunaix/spike.h>
6 #include <lunaix/kcmd.h>
7 #include <sys/mm/mm_defs.h>
8
9 /**
10  * @brief Reserve memory for kernel bootstrapping initialization
11  *
12  * @param bhctx
13  */
14 void
15 boot_begin(struct boot_handoff* bhctx)
16 {
17     bhctx->prepare(bhctx);
18     
19     // Identity-map the first 3GiB address spaces
20     pte_t* ptep  = mkl0tep(mkptep_va(VMS_SELF, 0));
21     pte_t pte    = mkpte_prot(KERNEL_DATA);
22     size_t count = page_count(KERNEL_RESIDENT, L0T_SIZE);
23
24     vmm_set_ptes_contig(ptep, pte_mkhuge(pte), L0T_SIZE, count);
25
26     struct boot_mmapent *mmap = bhctx->mem.mmap, *mmapent;
27     for (size_t i = 0; i < bhctx->mem.mmap_len; i++) {
28         mmapent = &mmap[i];
29         size_t size_pg = leaf_count(mmapent->size);
30         pfn_t start_pfn = pfn(mmapent->start);
31
32         if (mmapent->type == BOOT_MMAP_FREE) {
33             pmm_mark_chunk_free(start_pfn, size_pg);
34             continue;
35         }
36     }
37
38     /* Reserve region for all loaded modules */
39     for (size_t i = 0; i < bhctx->mods.mods_num; i++) {
40         struct boot_modent* mod = &bhctx->mods.entries[i];
41         unsigned int counts = leaf_count(mod->end - mod->start);
42
43         pmm_mark_chunk_occupied(pfn(mod->start), counts, PP_FGLOCKED);
44     }
45 }
46
47 extern u8_t __kboot_end; /* link/linker.ld */
48
49 /**
50  * @brief Release memory for kernel bootstrapping initialization
51  *
52  * @param bhctx
53  */
54 void
55 boot_end(struct boot_handoff* bhctx)
56 {
57     struct boot_mmapent *mmap = bhctx->mem.mmap, *mmapent;
58     for (size_t i = 0; i < bhctx->mem.mmap_len; i++) {
59         mmapent = &mmap[i];
60         size_t size_pg = leaf_count(mmapent->size);
61
62         if (mmapent->type == BOOT_MMAP_RCLM) {
63             pmm_mark_chunk_free(pfn(mmapent->start), size_pg);
64         }
65
66         if (mmapent->type == BOOT_MMAP_FREE) {
67             continue;
68         }
69     }
70
71     bhctx->release(bhctx);
72 }
73
74 /**
75  * @brief Clean up the boot stage code and data
76  *
77  */
78 void
79 boot_cleanup()
80 {
81     pte_t* ptep  = mkl0tep(mkptep_va(VMS_SELF, 0));
82     size_t count = page_count(KERNEL_RESIDENT, L0T_SIZE);
83     vmm_unset_ptes(ptep, count);
84 }
85
86 void
87 boot_parse_cmdline(struct boot_handoff* bhctx) {
88     if (!bhctx->kexec.len) {
89         return;
90     }
91
92     kcmd_parse_cmdline(bhctx->kexec.cmdline);
93 }