X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/1fe5f5eb5378a47bf0f3451762743c162e40faad..11b423249f224e3c9b7d940862c3cae310f81a23:/lunaix-os/kernel/mm/pmm.c?ds=inline diff --git a/lunaix-os/kernel/mm/pmm.c b/lunaix-os/kernel/mm/pmm.c index ffb51e6..72b57d7 100644 --- a/lunaix-os/kernel/mm/pmm.c +++ b/lunaix-os/kernel/mm/pmm.c @@ -1,42 +1,50 @@ -#include #include #include +#include +#include // This is a very large array... static struct pp_struct pm_table[PM_BMP_MAX_SIZE]; +export_symbol(debug, pmm, pm_table); static ptr_t max_pg; +export_symbol(debug, pmm, max_pg); void pmm_mark_page_free(ptr_t ppn) { + if ((pm_table[ppn].attr & PP_FGLOCKED)) { + return; + } pm_table[ppn].ref_counts = 0; } void -pmm_mark_page_occupied(pid_t owner, ptr_t ppn, pp_attr_t attr) +pmm_mark_page_occupied(ptr_t ppn, pp_attr_t attr) { pm_table[ppn] = - (struct pp_struct){ .owner = owner, .ref_counts = 1, .attr = attr }; + (struct pp_struct){ .ref_counts = 1, .attr = attr }; } void pmm_mark_chunk_free(ptr_t start_ppn, size_t page_count) { for (size_t i = start_ppn; i < start_ppn + page_count && i < max_pg; i++) { + if ((pm_table[i].attr & PP_FGLOCKED)) { + continue; + } pm_table[i].ref_counts = 0; } } void -pmm_mark_chunk_occupied(pid_t owner, - u32_t start_ppn, +pmm_mark_chunk_occupied(u32_t start_ppn, size_t page_count, pp_attr_t attr) { for (size_t i = start_ppn; i < start_ppn + page_count && i < max_pg; i++) { pm_table[i] = - (struct pp_struct){ .owner = owner, .ref_counts = 1, .attr = attr }; + (struct pp_struct){ .ref_counts = 1, .attr = attr }; } } @@ -48,19 +56,19 @@ volatile size_t pg_lookup_ptr; void pmm_init(ptr_t mem_upper_lim) { - max_pg = (PG_ALIGN(mem_upper_lim) >> 12); + max_pg = pfn(mem_upper_lim); pg_lookup_ptr = LOOKUP_START; // mark all as occupied for (size_t i = 0; i < PM_BMP_MAX_SIZE; i++) { pm_table[i] = - (struct pp_struct){ .owner = 0, .attr = 0, .ref_counts = 1 }; + (struct pp_struct){ .attr = 0, .ref_counts = 1 }; } } ptr_t -pmm_alloc_cpage(pid_t owner, size_t num_pages, pp_attr_t attr) +pmm_alloc_cpage(size_t num_pages, pp_attr_t attr) { size_t p1 = 0; size_t p2 = 0; @@ -73,13 +81,13 @@ pmm_alloc_cpage(pid_t owner, size_t num_pages, pp_attr_t attr) return NULLPTR; } - pmm_mark_chunk_occupied(owner, p1, num_pages, attr); + pmm_mark_chunk_occupied(p1, num_pages, attr); return p1 << 12; } ptr_t -pmm_alloc_page(pid_t owner, pp_attr_t attr) +pmm_alloc_page(pp_attr_t attr) { // Next fit approach. Maximize the throughput! ptr_t good_page_found = (ptr_t)NULL; @@ -91,7 +99,6 @@ pmm_alloc_page(pid_t owner, pp_attr_t attr) if (!pm->ref_counts) { *pm = (struct pp_struct){ .attr = attr, - .owner = owner, .ref_counts = 1 }; good_page_found = pg_lookup_ptr << 12; break; @@ -112,46 +119,46 @@ pmm_alloc_page(pid_t owner, pp_attr_t attr) } int -pmm_free_page(pid_t owner, ptr_t page) +pmm_free_one(ptr_t page, pp_attr_t attr_mask) { - struct pp_struct* pm = &pm_table[page >> 12]; + pfn_t ppfn = pfn(page); + struct pp_struct* pm = &pm_table[ppfn]; - // Is this a MMIO mapping or double free? - if ((page >> 12) >= max_pg || !(pm->ref_counts)) { + assert(ppfn < max_pg && pm->ref_counts); + if (pm->attr && !(pm->attr & attr_mask)) { return 0; } - // 如果是锁定页,则不作处理 - if ((pm->attr & PP_FGLOCKED)) { - return 0; - } - - // TODO: 检查权限,保证:1) 只有正在使用该页(包括被分享者)的进程可以释放; - // 2) 内核可释放所有页。 pm->ref_counts--; return 1; } int -pmm_ref_page(pid_t owner, ptr_t page) +pmm_ref_page(ptr_t page) { - (void)owner; // TODO: do smth with owner - - u32_t ppn = page >> 12; + u32_t ppn = pfn(page); if (ppn >= PM_BMP_MAX_SIZE) { return 0; } struct pp_struct* pm = &pm_table[ppn]; - if (ppn >= max_pg || !pm->ref_counts) { - return 0; - } + assert(ppn < max_pg && pm->ref_counts); pm->ref_counts++; return 1; } +void +pmm_set_attr(ptr_t page, pp_attr_t attr) +{ + struct pp_struct* pp = &pm_table[pfn(page)]; + + if (pp->ref_counts) { + pp->attr = attr; + } +} + struct pp_struct* pmm_query(ptr_t pa) {