physical page list mapping
[lunaix-os.git] / lunaix-os / arch / aarch64 / vmutils.c
1 #include <lunaix/mm/pagetable.h>
2 #include <lunaix/mm/page.h>
3 #include <lunaix/sections.h>
4
5 struct leaflet *
6 dup_leaflet(struct leaflet *leaflet)
7 {
8     ptr_t dest_va, src_va;
9     struct leaflet *new_leaflet;
10
11     new_leaflet = alloc_leaflet(leaflet_order(leaflet));
12
13     src_va = leaflet_mount(leaflet);
14     dest_va = vmap(new_leaflet, KERNEL_DATA);
15
16     memcpy((void *)dest_va, (void *)src_va, PAGE_SIZE);
17
18     leaflet_unmount(leaflet);
19     vunmap(dest_va, new_leaflet);
20
21     return new_leaflet;
22 }
23
24 static inline struct ppage*
25 __setup_pmem_map(ptr_t start, size_t plist_size)
26 {
27     pte_t pte, *ptep;
28     unsigned int nr_pages;
29
30     pte = mkpte(start, KERNEL_DATA);
31     ptep = mkl2tep_va(VMS_SELF, PMAP);
32     nr_pages = page_count(plist_size, L2T_SIZE);
33
34     vmm_set_ptes_contig(ptep, pte, L2T_SIZE, nr_pages);
35
36     return (struct ppage*)PMAP;
37 }
38
39 ptr_t 
40 pmm_arch_init_remap(struct pmem *memory, struct boot_handoff *bctx)
41 {
42     unsigned long plist_len, plist_size, nr_huges;
43     struct boot_mmapent *ment;
44
45     plist_len = leaf_count(bctx->mem.size);
46     plist_size = plist_len * sizeof(struct ppage);
47     nr_huges = page_count(plist_size, lnt_page_size(2));
48
49     ptr_t pkernel_end = to_kphysical(kernel_end);
50     pkernel_end = napot_upaligned(pkernel_end, L2T_SIZE);
51     pkernel_end += plist_size;
52
53     for (int i = 0; i < bctx->mem.mmap_len; i++)
54     {
55         ment = &bctx->mem.mmap[i];
56         if (ment->type != BOOT_MMAP_FREE) {
57             continue;
58         }
59
60         if (pkernel_end >= ment->start + ment->size) {
61             continue;
62         }
63
64         memory->pplist = __setup_pmem_map(pkernel_end, plist_size);;
65         memory->list_len = plist_len;
66         return pkernel_end;
67     }
68
69     fail("no_mem, unable to map plist");
70     return NULL;
71 }