finish lab2 page_table.c
This commit is contained in:
parent
5cf26522a5
commit
5eab974821
@ -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)
|
int query_in_pgtbl(vaddr_t * pgtbl, vaddr_t va, paddr_t * pa, pte_t ** entry)
|
||||||
{
|
{
|
||||||
// <lab2>
|
// <lab2>
|
||||||
|
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);
|
||||||
// </lab2>
|
// </lab2>
|
||||||
return 0;
|
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)
|
size_t len, vmr_prop_t flags)
|
||||||
{
|
{
|
||||||
// <lab2>
|
// <lab2>
|
||||||
|
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();
|
||||||
// </lab2>
|
// </lab2>
|
||||||
return 0;
|
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)
|
int unmap_range_in_pgtbl(vaddr_t * pgtbl, vaddr_t va, size_t len)
|
||||||
{
|
{
|
||||||
// <lab2>
|
// <lab2>
|
||||||
|
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();
|
||||||
// </lab2>
|
// </lab2>
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user