add generic kremap for kernel remapping
[lunaix-os.git] / lunaix-os / arch / x86 / boot / i386 / kremap32.c
index eac579315acd89981dfb4fdbf23427240c5c32e1..5a8949ea45301a346abd3b9a0507ae0b12f9654c 100644 (file)
 #define __BOOT_CODE__
 
-#include <lunaix/mm/pagetable.h>
-#include <lunaix/compiler.h>
-#include <lunaix/sections.h>
-
-#include <sys/boot/bstage.h>
+#include <asm/boot_stage.h>
 #include <asm/mm_defs.h>
-
-#define PF_X 0x1
-#define PF_W 0x2
-#define ksection_maps autogen_name(ksecmap)
-
-extern_autogen(ksecmap);
-
-bridge_farsym(__kexec_text_start);
-bridge_farsym(ksection_maps);
+#include <asm-generic/init_pagetable.h>
 
 // define the initial page table layout
-struct kernel_map;
-
-static struct kernel_map kernel_pt __section(".kpg");
-export_symbol(debug, boot, kernel_pt);
-
 struct kernel_map 
 {
-    pte_t l0t[_PAGE_LEVEL_SIZE];
-    pte_t pg_mnt[_PAGE_LEVEL_SIZE];
-
     struct {
         pte_t _lft[_PAGE_LEVEL_SIZE];
     } kernel_lfts[16];
 } align(4);
 
-static void boot_text
+static struct kernel_map kernel_pt __section(".kpg");
+export_symbol(debug, boot, kernel_pt);
+
+static ptr_t boot_text
 do_remap()
 {
-    struct kernel_map* kpt_pa = (struct kernel_map*)to_kphysical(&kernel_pt);
-    
-    size_t mia_casa_i   = pfn_at(KERNEL_RESIDENT, L0T_SIZE);
-    pte_t* klptep       = (pte_t*) &kpt_pa->l0t[mia_casa_i];
-    pte_t* ktep         = (pte_t*)  kpt_pa->kernel_lfts;    
-    pte_t* boot_l0tep   = (pte_t*)  kpt_pa;
+    struct pt_alloc alloc;
+    struct ptw_state ptw;
+    pte_t pte;
 
-    set_pte(boot_l0tep, pte_mkhuge(mkpte_prot(KERNEL_PGTAB)));
+    init_pt_alloc(&alloc, to_kphysical(&kernel_pt), sizeof(kernel_pt));
+    init_ptw_state(&ptw, &alloc, kpt_alloc_table(&alloc));
 
-    // --- 将内核重映射至高半区 ---
+    pte = pte_mkhuge(mkpte_prot(KERNEL_DATA));
+    kpt_set_ptes(&ptw, 0, pte, L0T_SIZE, 1);
 
-    // Hook the kernel reserved LFTs onto L0T
-    pte_t pte = mkpte((ptr_t)ktep, KERNEL_PGTAB);
-    
-    for (u32_t i = 0; i < KEXEC_RSVD; i++) {
-        pte = pte_setpaddr(pte, (ptr_t)&kpt_pa->kernel_lfts[i]);
-        set_pte(klptep, pte);
+    kpt_mktable_at(&ptw, KMAP, L0T_SIZE);
+    kpt_mktable_at(&ptw, VMAP, L0T_SIZE);
 
-        klptep++;
-    }
+    kpt_migrate_highmem(&ptw);
 
-    struct ksecmap* maps;
-    struct ksection* section;
-    pfn_t pgs;
-    pte_t *kmntep;
+    pte = mkpte(__ptr(ptw.root), KERNEL_PGTAB);
+    kpt_set_ptes(&ptw, VMS_SELF, pte, L0T_SIZE, 1);
 
-    maps = (struct ksecmap*)to_kphysical(__far(ksection_maps));
-    ktep += pfn(to_kphysical(__far(__kexec_text_start)));
-
-    // Ensure the size of kernel is within the reservation
-    if (leaf_count(maps->ksize) > KEXEC_RSVD * _PAGE_LEVEL_SIZE) 
-    {
-        // ERROR: require more pages
-        //  here should do something else other than head into blocking
-        asm("ud2");
-    }
-
-    // Now, map the sections
-
-    for (unsigned int i = 0; i < maps->num; i++)
-    {
-        section = &maps->secs[i];
-
-        if (section->va < KERNEL_RESIDENT) {
-            continue;
-        }
-
-        pte = mkpte_prot(KERNEL_RDONLY);
-        if ((section->flags & PF_X)) {
-            pte = pte_mkexec(pte);
-        }
-        if ((section->flags & PF_W)) {
-            pte = pte_mkwritable(pte);
-        }
-
-        pgs = leaf_count(section->size);
-        for (pfn_t j = 0; j < pgs; j++)
-        {
-            pte = pte_setpaddr(pte, section->pa + page_addr(j));
-            set_pte(ktep, pte);
-
-            ktep++;
-        }
-    }
-
-    // set mount point
-    kmntep = (pte_t*) &kpt_pa->l0t[pfn_at(PG_MOUNT_1, L0T_SIZE)];
-    set_pte(kmntep, mkpte((ptr_t)kpt_pa->pg_mnt, KERNEL_PGTAB));
-
-    // Build up self-reference
-    int level = (VMS_SELF / L0T_SIZE) & _PAGE_LEVEL_MASK;
-    
-    pte = mkpte_root((ptr_t)kpt_pa, KERNEL_PGTAB);
-    set_pte(&boot_l0tep[level], pte);
+    return __ptr(ptw.root);
 }
 
 ptr_t boot_text
@@ -119,7 +47,5 @@ remap_kernel()
         ((u8_t*)kmap_pa)[i] = 0;
     }
 
-    do_remap();
-
-    return kmap_pa;
+    return do_remap();
 }
\ No newline at end of file