Don't override attributes when creating a new paging table
This commit is contained in:
parent
b4cab2922c
commit
154f7c6d6c
1 changed files with 37 additions and 23 deletions
|
@ -198,6 +198,20 @@ fn mapDirEntry(dir: *Directory, virt_start: usize, virt_end: usize, phys_start:
|
||||||
const entry = virtToDirEntryIdx(virt_start);
|
const entry = virtToDirEntryIdx(virt_start);
|
||||||
var dir_entry = &dir.entries[entry];
|
var dir_entry = &dir.entries[entry];
|
||||||
|
|
||||||
|
// Only create a new table if one hasn't already been created for this dir entry.
|
||||||
|
// Prevents us from overriding previous mappings.
|
||||||
|
var table: *Table = undefined;
|
||||||
|
if (dir.tables[entry]) |tbl| {
|
||||||
|
table = tbl;
|
||||||
|
} else {
|
||||||
|
// Create a table and put the physical address in the dir entry
|
||||||
|
table = &(try allocator.alignedAlloc(Table, @truncate(u29, PAGE_SIZE_4KB), 1))[0];
|
||||||
|
@memset(@ptrCast([*]u8, table), 0, @sizeOf(Table));
|
||||||
|
const table_phys_addr = @ptrToInt(mem.virtToPhys(table));
|
||||||
|
dir_entry.* |= DENTRY_PAGE_ADDR & table_phys_addr;
|
||||||
|
dir.tables[entry] = table;
|
||||||
|
}
|
||||||
|
|
||||||
setAttribute(dir_entry, DENTRY_PRESENT);
|
setAttribute(dir_entry, DENTRY_PRESENT);
|
||||||
setAttribute(dir_entry, DENTRY_WRITE_THROUGH);
|
setAttribute(dir_entry, DENTRY_WRITE_THROUGH);
|
||||||
clearAttribute(dir_entry, DENTRY_4MB_PAGES);
|
clearAttribute(dir_entry, DENTRY_4MB_PAGES);
|
||||||
|
@ -220,20 +234,6 @@ fn mapDirEntry(dir: *Directory, virt_start: usize, virt_end: usize, phys_start:
|
||||||
setAttribute(dir_entry, DENTRY_CACHE_DISABLED);
|
setAttribute(dir_entry, DENTRY_CACHE_DISABLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only create a new table if one hasn't already been created for this dir entry.
|
|
||||||
// Prevents us from overriding previous mappings.
|
|
||||||
var table: *Table = undefined;
|
|
||||||
if (dir.tables[entry]) |tbl| {
|
|
||||||
table = tbl;
|
|
||||||
} else {
|
|
||||||
// Create a table and put the physical address in the dir entry
|
|
||||||
table = &(try allocator.alignedAlloc(Table, @truncate(u29, PAGE_SIZE_4KB), 1))[0];
|
|
||||||
@memset(@ptrCast([*]u8, table), 0, @sizeOf(Table));
|
|
||||||
const table_phys_addr = @ptrToInt(mem.virtToPhys(table));
|
|
||||||
dir_entry.* |= DENTRY_PAGE_ADDR & table_phys_addr;
|
|
||||||
dir.tables[entry] = table;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Map the table entries within the requested space
|
// Map the table entries within the requested space
|
||||||
var virt = virt_start;
|
var virt = virt_start;
|
||||||
var phys = phys_start;
|
var phys = phys_start;
|
||||||
|
@ -498,7 +498,8 @@ test "virtToTableEntryIdx" {
|
||||||
test "mapDirEntry" {
|
test "mapDirEntry" {
|
||||||
var allocator = std.heap.page_allocator;
|
var allocator = std.heap.page_allocator;
|
||||||
var dir: Directory = Directory{ .entries = [_]DirectoryEntry{0} ** ENTRIES_PER_DIRECTORY, .tables = [_]?*Table{null} ** ENTRIES_PER_DIRECTORY };
|
var dir: Directory = Directory{ .entries = [_]DirectoryEntry{0} ** ENTRIES_PER_DIRECTORY, .tables = [_]?*Table{null} ** ENTRIES_PER_DIRECTORY };
|
||||||
var phys: usize = 0 * PAGE_SIZE_4MB;
|
{
|
||||||
|
const phys: usize = 0 * PAGE_SIZE_4MB;
|
||||||
const phys_end: usize = phys + PAGE_SIZE_4MB;
|
const phys_end: usize = phys + PAGE_SIZE_4MB;
|
||||||
const virt: usize = 1 * PAGE_SIZE_4MB;
|
const virt: usize = 1 * PAGE_SIZE_4MB;
|
||||||
const virt_end: usize = virt + PAGE_SIZE_4MB;
|
const virt_end: usize = virt + PAGE_SIZE_4MB;
|
||||||
|
@ -508,6 +509,19 @@ test "mapDirEntry" {
|
||||||
const entry = dir.entries[entry_idx];
|
const entry = dir.entries[entry_idx];
|
||||||
const table = dir.tables[entry_idx] orelse unreachable;
|
const table = dir.tables[entry_idx] orelse unreachable;
|
||||||
checkDirEntry(entry, virt, virt_end, phys, .{ .kernel = true, .writable = true, .cachable = true }, table, true);
|
checkDirEntry(entry, virt, virt_end, phys, .{ .kernel = true, .writable = true, .cachable = true }, table, true);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const phys: usize = 7 * PAGE_SIZE_4MB;
|
||||||
|
const phys_end: usize = phys + PAGE_SIZE_4MB;
|
||||||
|
const virt: usize = 8 * PAGE_SIZE_4MB;
|
||||||
|
const virt_end: usize = virt + PAGE_SIZE_4MB;
|
||||||
|
try mapDirEntry(&dir, virt, virt_end, phys, phys_end, .{ .kernel = false, .writable = false, .cachable = false }, allocator);
|
||||||
|
|
||||||
|
const entry_idx = virtToDirEntryIdx(virt);
|
||||||
|
const entry = dir.entries[entry_idx];
|
||||||
|
const table = dir.tables[entry_idx] orelse unreachable;
|
||||||
|
checkDirEntry(entry, virt, virt_end, phys, .{ .kernel = false, .writable = false, .cachable = false }, table, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test "mapDirEntry returns errors correctly" {
|
test "mapDirEntry returns errors correctly" {
|
||||||
|
|
Loading…
Reference in a new issue