Compare commits

..

No commits in common. "654b228f105530614983f50cf3f3850d9b8ee62c" and "da5335410db3af69addd9a593ea04450f5cb2ec2" have entirely different histories.

2 changed files with 5 additions and 125 deletions

View File

@ -5,21 +5,10 @@ const interrupts = @import("interrupts.zig");
pub const PAGE_SIZE = 4096;
// FIXME: Check if it's supported first.
fn enableNX() void {
asm volatile (
\\ mov $0xC0000080, %rcx
\\ rdmsr
\\ or $0x800, %eax
\\ wrmsr
);
}
// Initialize platform-specific components.
pub fn platformInit() void {
gdt.setupGDT();
idt.setupIDT();
enableNX();
}
// Initialize platform-specific components just before beginning multitasking.

View File

@ -2,10 +2,9 @@ const std = @import("std");
const easyboot = @cImport(@cInclude("easyboot.h"));
const mmap = @import("../../mmap.zig");
const pmm = @import("../../pmm.zig");
const platform = @import("platform.zig");
const USER_ADDRESS_RANGE_END = 0x0000_7fff_ffff_ffff;
pub const PHYSICAL_MAPPING_BASE = 0xffff_8000_0000_0000;
const PHYSICAL_MAPPING_BASE = 0xffff_8000_0000_0000;
const HUGE_PAGE_SIZE = 0x200000; // 2 MiB
pub const PageTableEntry = packed struct {
@ -15,7 +14,7 @@ pub const PageTableEntry = packed struct {
write_through: u1,
cache_disabled: u1,
accessed: u1,
reserved: u1,
ignore0: u1,
larger_pages: u1,
global: u1,
available: u3,
@ -32,7 +31,7 @@ pub const PageTableEntry = packed struct {
}
pub fn clear(self: *PageTableEntry) void {
self.* = std.mem.zeroes(PageTableEntry);
self = std.mem.zeroes(@TypeOf(self));
}
};
@ -40,7 +39,7 @@ pub const PageDirectory = struct {
entries: [512]PageTableEntry,
};
pub const Flags = enum(u32) {
const Flags = enum(u32) {
None = 0,
ReadWrite = 1,
User = 2,
@ -69,7 +68,6 @@ fn hasFlag(flags: u32, flag: Flags) u1 {
}
fn updatePageTableEntry(entry: *PageTableEntry, phys: pmm.PhysFrame, flags: u32) void {
entry.clear();
entry.present = 1;
entry.read_write = hasFlag(flags, Flags.ReadWrite);
entry.user = hasFlag(flags, Flags.User);
@ -82,7 +80,6 @@ fn updatePageTableEntry(entry: *PageTableEntry, phys: pmm.PhysFrame, flags: u32)
fn setUpParentPageTableEntry(allocator: *pmm.FrameAllocator, pte: *PageTableEntry, flags: u32, base: usize) !void {
if (pte.present == 0) {
pte.clear();
const frame = try pmm.allocFrame(allocator);
pte.present = 1;
pte.set_address(frame.address);
@ -110,8 +107,8 @@ pub fn map(allocator: *pmm.FrameAllocator, directory: *PageDirectory, base: usiz
if (l2.larger_pages == 1) return error.MemoryAlreadyInUse;
if (use_huge_pages) {
updatePageTableEntry(l2, phys, flags);
l2.larger_pages = 1;
updatePageTableEntry(l2, phys, flags);
return;
}
@ -122,108 +119,6 @@ pub fn map(allocator: *pmm.FrameAllocator, directory: *PageDirectory, base: usiz
updatePageTableEntry(l1, phys, flags);
}
pub fn getEntry(directory: *PageDirectory, base: usize, virt_address: u64) ?*PageTableEntry {
const indexes = calculatePageTableIndexes(virt_address);
const l4 = &directory.entries[indexes.level4];
if (l4.present == 0) return null;
const l3 = &getTable(l4, base).entries[indexes.level3];
if (l3.present == 0) return null;
if (l3.larger_pages == 1) return l3;
const l2 = &getTable(l3, base).entries[indexes.level2];
if (l2.present == 0) return null;
if (l2.larger_pages == 1) return l2;
const l1 = &getTable(l2, base).entries[indexes.level1];
if (l1.present == 0) return null;
return l1;
}
pub fn copyToUser(directory: *PageDirectory, base: usize, user: usize, kernel: [*]const u8, size: usize) !void {
const remainder: usize = @rem(user, platform.PAGE_SIZE);
const user_page = user - remainder;
var user_address = user;
var kernel_ptr = kernel;
var count = size;
if (user_address != user_page) {
const pte = getEntry(directory, base, user_page) orelse return error.MemoryNotInUse;
const frame = pmm.PhysFrame{ .address = pte.get_address() };
const amount: usize = @min((platform.PAGE_SIZE - remainder), count);
const virt = frame.virtualAddress(base) + remainder;
@memcpy(@as([*]u8, @ptrFromInt(virt))[0..amount], kernel_ptr[0..amount]);
kernel_ptr += amount;
user_address += amount;
count -= amount;
}
while (count > 0) {
const pte = getEntry(directory, base, user_address) orelse return error.MemoryNotInUse;
const frame = pmm.PhysFrame{ .address = pte.get_address() };
const amount: usize = @min(platform.PAGE_SIZE, count);
const virt = frame.virtualAddress(base);
@memcpy(@as([*]u8, @ptrFromInt(virt))[0..amount], kernel_ptr[0..amount]);
kernel_ptr += amount;
user_address += amount;
count -= amount;
}
return;
}
pub fn memsetUser(directory: *PageDirectory, base: usize, user: usize, elem: u8, size: usize) !void {
const remainder: usize = @rem(user, platform.PAGE_SIZE);
const user_page = user - remainder;
var user_address = user;
var count = size;
if (user_address != user_page) {
const pte = getEntry(directory, base, user_page) orelse return error.MemoryNotInUse;
const frame = pmm.PhysFrame{ .address = pte.get_address() };
const amount: usize = @min((platform.PAGE_SIZE - remainder), count);
const virt = frame.virtualAddress(base) + remainder;
@memset(@as([*]u8, @ptrFromInt(virt))[0..amount], elem);
user_address += amount;
count -= amount;
}
while (count > 0) {
const pte = getEntry(directory, base, user_address) orelse return error.MemoryNotInUse;
const frame = pmm.PhysFrame{ .address = pte.get_address() };
const amount: usize = @min(platform.PAGE_SIZE, count);
const virt = frame.virtualAddress(base);
@memset(@as([*]u8, @ptrFromInt(virt))[0..amount], elem);
user_address += amount;
count -= amount;
}
return;
}
pub fn allocAndMap(allocator: *pmm.FrameAllocator, directory: *PageDirectory, base: u64, pages: usize, flags: u32) !void {
var virt = base;
var i: usize = 0;
while (i < pages) {
const frame = try pmm.allocFrame(allocator);
try map(allocator, directory, PHYSICAL_MAPPING_BASE, virt, frame, flags, false);
virt += platform.PAGE_SIZE;
i += 1;
}
}
fn mapPhysicalMemory(allocator: *pmm.FrameAllocator, tag: *easyboot.multiboot_tag_mmap_t, directory: *PageDirectory, base: usize, flags: u32) !void {
const address_space_size = mmap.getAddressSpaceSize(tag) orelse return error.InvalidMemoryMap;
const address_space_pages = address_space_size / HUGE_PAGE_SIZE;
@ -300,10 +195,6 @@ pub fn readPageDirectory() *PageDirectory {
return directory;
}
pub fn getPhysicalPageDirectory(directory: *PageDirectory) *PageDirectory {
return @ptrFromInt(@intFromPtr(directory) - @as(usize, PHYSICAL_MAPPING_BASE));
}
pub fn setPageDirectory(directory: *PageDirectory) void {
asm volatile ("mov %[dir], %%cr3"
: