3 #include <lunaix/mm/pagetable.h>
4 #include <lunaix/compiler.h>
5 #include <lunaix/sections.h>
7 #include <sys/boot/bstage.h>
8 #include <asm/mm_defs.h>
12 #define ksection_maps autogen_name(ksecmap)
14 extern_autogen(ksecmap);
16 bridge_farsym(__kexec_text_start);
17 bridge_farsym(ksection_maps);
19 // define the initial page table layout
22 static struct kernel_map kernel_pt __section(".kpg");
23 export_symbol(debug, boot, kernel_pt);
27 pte_t l0t[_PAGE_LEVEL_SIZE];
28 pte_t pg_mnt[_PAGE_LEVEL_SIZE];
31 pte_t _lft[_PAGE_LEVEL_SIZE];
38 struct kernel_map* kpt_pa = (struct kernel_map*)to_kphysical(&kernel_pt);
40 size_t mia_casa_i = pfn_at(KERNEL_RESIDENT, L0T_SIZE);
41 pte_t* klptep = (pte_t*) &kpt_pa->l0t[mia_casa_i];
42 pte_t* ktep = (pte_t*) kpt_pa->kernel_lfts;
43 pte_t* boot_l0tep = (pte_t*) kpt_pa;
45 set_pte(boot_l0tep, pte_mkhuge(mkpte_prot(KERNEL_PGTAB)));
49 // Hook the kernel reserved LFTs onto L0T
50 pte_t pte = mkpte((ptr_t)ktep, KERNEL_PGTAB);
52 for (u32_t i = 0; i < KEXEC_RSVD; i++) {
53 pte = pte_setpaddr(pte, (ptr_t)&kpt_pa->kernel_lfts[i]);
60 struct ksection* section;
64 maps = (struct ksecmap*)to_kphysical(__far(ksection_maps));
65 ktep += pfn(to_kphysical(__far(__kexec_text_start)));
67 // Ensure the size of kernel is within the reservation
68 if (leaf_count(maps->ksize) > KEXEC_RSVD * _PAGE_LEVEL_SIZE)
70 // ERROR: require more pages
71 // here should do something else other than head into blocking
75 // Now, map the sections
77 for (unsigned int i = 0; i < maps->num; i++)
79 section = &maps->secs[i];
81 if (section->va < KERNEL_RESIDENT) {
85 pte = mkpte_prot(KERNEL_RDONLY);
86 if ((section->flags & PF_X)) {
87 pte = pte_mkexec(pte);
89 if ((section->flags & PF_W)) {
90 pte = pte_mkwritable(pte);
93 pgs = leaf_count(section->size);
94 for (pfn_t j = 0; j < pgs; j++)
96 pte = pte_setpaddr(pte, section->pa + page_addr(j));
104 kmntep = (pte_t*) &kpt_pa->l0t[pfn_at(PG_MOUNT_1, L0T_SIZE)];
105 set_pte(kmntep, mkpte((ptr_t)kpt_pa->pg_mnt, KERNEL_PGTAB));
107 // Build up self-reference
108 int level = (VMS_SELF / L0T_SIZE) & _PAGE_LEVEL_MASK;
110 pte = mkpte_root((ptr_t)kpt_pa, KERNEL_PGTAB);
111 set_pte(&boot_l0tep[level], pte);
117 ptr_t kmap_pa = to_kphysical(&kernel_pt);
118 for (size_t i = 0; i < sizeof(kernel_pt); i++) {
119 ((u8_t*)kmap_pa)[i] = 0;