From 5eab97482131838fde73763324dfb66e68d44361 Mon Sep 17 00:00:00 2001 From: KAAAsS Date: Thu, 13 May 2021 14:34:13 +0800 Subject: [PATCH] finish lab2 page_table.c --- lab2/kernel/mm/page_table.c | 87 ++++++++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 2 deletions(-) diff --git a/lab2/kernel/mm/page_table.c b/lab2/kernel/mm/page_table.c index 0109d93..bb14fd6 100644 --- a/lab2/kernel/mm/page_table.c +++ b/lab2/kernel/mm/page_table.c @@ -162,7 +162,24 @@ static int get_next_ptp(ptp_t * cur_ptp, u32 level, vaddr_t va, int query_in_pgtbl(vaddr_t * pgtbl, vaddr_t va, paddr_t * pa, pte_t ** entry) { // + ptp_t * cur_ptp = (ptp_t *) pgtbl, *next_ptp; + int page_type; + // 遍历 L0-L3 + for (u32 cur_level = 0; cur_level < 4; cur_level++) { + page_type = get_next_ptp(cur_ptp, cur_level, va, &next_ptp, entry, false); + if (page_type < 0) { + // 无法映射 + return page_type; + } else if (page_type == BLOCK_PTP) { + // 遇到块项直接返回 + break; + } else { + // 遇到页表项,向下遍历 + cur_ptp = next_ptp; + } + } + *pa = GET_PADDR_IN_PTE((*entry)) | (va & PAGE_MASK); // return 0; } @@ -186,7 +203,40 @@ int map_range_in_pgtbl(vaddr_t * pgtbl, vaddr_t va, paddr_t pa, size_t len, vmr_prop_t flags) { // - + vaddr_t va_start = va, va_end = va + len, va_cur; + ptp_t * cur_ptp, *next_ptp; + int page_type; + u32 cur_level; + pte_t *entry; + u64 cur_pfn; + // 遍历所有页 + cur_pfn = pa >> PAGE_SHIFT; + va_start &= ~PAGE_MASK; + va_end &= ~PAGE_MASK; + if (va_end < va + len) { + va_end++; // 有不完整的一页 + } + for (va_cur = va_start; va_cur < va_end; va_cur += PAGE_SIZE) { + // 创建一页 + cur_ptp = (ptp_t *) pgtbl; + for (cur_level = 0; cur_level < 4; cur_level++) { + page_type = get_next_ptp(cur_ptp, cur_level, va, &next_ptp, &entry, true); + if (page_type < 0) { + // 无法映射 + return page_type; + } else if (page_type == BLOCK_PTP) { + // 目前只支持页映射,遇到块项直接返回 + return -ENOMAPPING; + } else { + // 遇到页表项,向下遍历 + cur_ptp = next_ptp; + } + } + // 配置页 + set_pte_flags(entry, flags, USER_PTE); + entry->l3_page.pfn = cur_pfn++; + } + flush_tlb(); // return 0; } @@ -207,7 +257,40 @@ int map_range_in_pgtbl(vaddr_t * pgtbl, vaddr_t va, paddr_t pa, int unmap_range_in_pgtbl(vaddr_t * pgtbl, vaddr_t va, size_t len) { // - + vaddr_t va_start = va, va_end = va + len, va_cur; + ptp_t * cur_ptp, *next_ptp; + int page_type; + u32 cur_level; + pte_t *entry; + // 遍历所有页 + va_start &= ~PAGE_MASK; + va_end &= ~PAGE_MASK; + if (va_end < va + len) { + va_end++; // 有不完整的一页 + } + for (va_cur = va_start; va_cur < va_end; va_cur += PAGE_SIZE) { + // 创建一页 + cur_ptp = (ptp_t *) pgtbl; + for (cur_level = 0; cur_level < 4; cur_level++) { + page_type = get_next_ptp(cur_ptp, cur_level, va, &next_ptp, &entry, false); + if (page_type < 0) { + // 无法映射 + break; + } else if (page_type == BLOCK_PTP) { + // 目前只支持页映射,遇到块项直接返回 + return -ENOMAPPING; + } else { + // 遇到页表项,向下遍历 + cur_ptp = next_ptp; + } + } + if (cur_level != 4) { + continue; + } + // 配置页 + entry->pte = 0; + } + flush_tlb(); // return 0; }