pluto/src/kernel/mem.zig
DrDeano 2c91e6f9d0
Remove the old and in with the new
Added the new testing to the OS files

Some spelling
INOUT => IN/OUT
Added some doc comments to log

Added the new runtime to the build + added the None test mode

Moved some stuff around
None test mode is the default to run/build the OS normally with no runtime tests.

Add the new runtime testing to the CI


Updated README and CI


Increased timeout


Print the log message


Spelling


Move runtime to test folder


Add new RT to tty


Add a log to use the unmapped memory to cause page fault in release


Ensure the integer overflow happens even in release builds
2020-06-23 12:43:52 +01:00

114 lines
3.7 KiB
Zig

const std = @import("std");
const expectEqual = std.testing.expectEqual;
const log = @import("log.zig");
pub const Module = struct {
/// The region of memory occupied by the module
region: Range,
/// The module's name
name: []const u8,
};
pub const Map = struct {
/// The virtual range to reserve
virtual: Range,
/// The physical range to map to, if any
physical: ?Range,
};
/// A range of memory
pub const Range = struct {
/// The start of the range, inclusive
start: usize,
/// The end of the range, exclusive
end: usize,
};
pub const MemProfile = struct {
/// The virtual end address of the kernel code.
vaddr_end: [*]u8,
/// The virtual end address of the kernel code.
vaddr_start: [*]u8,
/// The physical end address of the kernel code.
physaddr_end: [*]u8,
/// The physical start address of the kernel code.
physaddr_start: [*]u8,
/// The amount of memory in the system, in kilobytes.
mem_kb: usize,
/// The modules loaded into memory at boot.
modules: []Module,
/// The virtual regions of reserved memory. Should not include what is tracked by the vaddr_* fields but should include the regions occupied by the modules. These are reserved and mapped by the VMM
virtual_reserved: []Map,
/// The physical regions of reserved memory. Should not include what is tracked by the physaddr_* fields but should include the regions occupied by the modules. These are reserved by the PMM
physical_reserved: []Range,
/// The allocator to use before a heap can be set up.
fixed_allocator: std.heap.FixedBufferAllocator,
};
/// The size of the fixed allocator used before the heap is set up. Set to 1MiB.
pub const FIXED_ALLOC_SIZE: usize = 1024 * 1024;
/// The kernel's virtual address offset. It's assigned in the init function and this file's tests.
/// We can't just use KERNEL_ADDR_OFFSET since using externs in the virtToPhys test is broken in
/// release-safe. This is a workaround until that is fixed.
pub var ADDR_OFFSET: usize = undefined;
///
/// Convert a virtual address to its physical counterpart by subtracting the kernel virtual offset from the virtual address.
///
/// Arguments:
/// IN virt: var - The virtual address to covert. Either an integer or pointer.
///
/// Return: @TypeOf(virt)
/// The physical address.
///
pub fn virtToPhys(virt: var) @TypeOf(virt) {
const T = @TypeOf(virt);
return switch (@typeInfo(T)) {
.Pointer => @intToPtr(T, @ptrToInt(virt) - ADDR_OFFSET),
.Int => virt - ADDR_OFFSET,
else => @compileError("Only pointers and integers are supported"),
};
}
///
/// Convert a physical address to its virtual counterpart by adding the kernel virtual offset to the physical address.
///
/// Arguments:
/// IN phys: var - The physical address to covert. Either an integer or pointer.
///
/// Return: @TypeOf(virt)
/// The virtual address.
///
pub fn physToVirt(phys: var) @TypeOf(phys) {
const T = @TypeOf(phys);
return switch (@typeInfo(T)) {
.Pointer => @intToPtr(T, @ptrToInt(phys) + ADDR_OFFSET),
.Int => phys + ADDR_OFFSET,
else => @compileError("Only pointers and integers are supported"),
};
}
test "physToVirt" {
ADDR_OFFSET = 0xC0000000;
const offset: usize = ADDR_OFFSET;
expectEqual(physToVirt(@as(usize, 0)), offset + 0);
expectEqual(physToVirt(@as(usize, 123)), offset + 123);
expectEqual(@ptrToInt(physToVirt(@intToPtr(*align(1) usize, 123))), offset + 123);
}
test "virtToPhys" {
ADDR_OFFSET = 0xC0000000;
const offset: usize = ADDR_OFFSET;
expectEqual(virtToPhys(offset + 0), 0);
expectEqual(virtToPhys(offset + 123), 123);
expectEqual(@ptrToInt(virtToPhys(@intToPtr(*align(1) usize, offset + 123))), 123);
}