pluto/src/kernel/arch/x86/arch.zig

616 lines
20 KiB
Zig
Raw Normal View History

const std = @import("std");
const Allocator = std.mem.Allocator;
2020-08-23 14:32:32 +01:00
const log = std.log.scoped(.x86_arch);
const builtin = @import("builtin");
Initial scheduler Fix TSS Also change to .{} syntax where appropriate. Added the SS segment Fixed spelling Refactoring GDT Multitasking working for now WIP scheduler Refactored Bitmap a bit WIP still Task switching working Handlers return the stack pointer that will be used to restore the tasks stack, normal handlers will return the same stack pointer it was called with where task switching will return the stack pointer of the next task and restore its state using the interrupt stub. Initial scheduler done Created a stage 2 init task Change u32 to usize Move Task to arch specific WIP WIP2 Removed esp from task, replaced with stack_pointer Removed the debug logs Fixed init task stack Change pickNextTask to pointer manipulation This allows less allocations so faster switching Temporary enable interrupts for some runtime tests PIT and RTC need interrupts enabled to run their runtime tests Renamed schedule => pickNextTask, comptime bitmap for pids not task init And some other stuff: No pub for the task anymore Use the leak detector allocator Fmt Fix unit tests And some other stuff :P PR review Moved Task out of arch and have the stack init in the arch file Mocking clean up Removed commented code Renamed createTask to scheduleTask where the user will have to provide a task to schedule Removed redundant pub in log runtime test Removed global allocator for scheduler Cleaner assembly in paging Fmt Added new Scheduler test mode Added new test mode to CI Removed one of the prints Added doc comment, task test for i386 Removed test WIP Runtime tests work Have a global set in one task and reacted to in another. Also test that local variables are preserved after a task switch. Removed new lines Increased line length Move the allocation of the bool above the task creation
2020-07-18 22:46:24 +01:00
const cmos = @import("cmos.zig");
const gdt = @import("gdt.zig");
const idt = @import("idt.zig");
const irq = @import("irq.zig");
const isr = @import("isr.zig");
Initial scheduler Fix TSS Also change to .{} syntax where appropriate. Added the SS segment Fixed spelling Refactoring GDT Multitasking working for now WIP scheduler Refactored Bitmap a bit WIP still Task switching working Handlers return the stack pointer that will be used to restore the tasks stack, normal handlers will return the same stack pointer it was called with where task switching will return the stack pointer of the next task and restore its state using the interrupt stub. Initial scheduler done Created a stage 2 init task Change u32 to usize Move Task to arch specific WIP WIP2 Removed esp from task, replaced with stack_pointer Removed the debug logs Fixed init task stack Change pickNextTask to pointer manipulation This allows less allocations so faster switching Temporary enable interrupts for some runtime tests PIT and RTC need interrupts enabled to run their runtime tests Renamed schedule => pickNextTask, comptime bitmap for pids not task init And some other stuff: No pub for the task anymore Use the leak detector allocator Fmt Fix unit tests And some other stuff :P PR review Moved Task out of arch and have the stack init in the arch file Mocking clean up Removed commented code Renamed createTask to scheduleTask where the user will have to provide a task to schedule Removed redundant pub in log runtime test Removed global allocator for scheduler Cleaner assembly in paging Fmt Added new Scheduler test mode Added new test mode to CI Removed one of the prints Added doc comment, task test for i386 Removed test WIP Runtime tests work Have a global set in one task and reacted to in another. Also test that local variables are preserved after a task switch. Removed new lines Increased line length Move the allocation of the bool above the task creation
2020-07-18 22:46:24 +01:00
const paging = @import("paging.zig");
const pic = @import("pic.zig");
const pci = @import("pci.zig");
const pit = @import("pit.zig");
const rtc = @import("rtc.zig");
2020-06-04 14:39:37 +01:00
const serial = @import("serial.zig");
2019-07-31 22:41:22 +01:00
const syscalls = @import("syscalls.zig");
Initial scheduler Fix TSS Also change to .{} syntax where appropriate. Added the SS segment Fixed spelling Refactoring GDT Multitasking working for now WIP scheduler Refactored Bitmap a bit WIP still Task switching working Handlers return the stack pointer that will be used to restore the tasks stack, normal handlers will return the same stack pointer it was called with where task switching will return the stack pointer of the next task and restore its state using the interrupt stub. Initial scheduler done Created a stage 2 init task Change u32 to usize Move Task to arch specific WIP WIP2 Removed esp from task, replaced with stack_pointer Removed the debug logs Fixed init task stack Change pickNextTask to pointer manipulation This allows less allocations so faster switching Temporary enable interrupts for some runtime tests PIT and RTC need interrupts enabled to run their runtime tests Renamed schedule => pickNextTask, comptime bitmap for pids not task init And some other stuff: No pub for the task anymore Use the leak detector allocator Fmt Fix unit tests And some other stuff :P PR review Moved Task out of arch and have the stack init in the arch file Mocking clean up Removed commented code Renamed createTask to scheduleTask where the user will have to provide a task to schedule Removed redundant pub in log runtime test Removed global allocator for scheduler Cleaner assembly in paging Fmt Added new Scheduler test mode Added new test mode to CI Removed one of the prints Added doc comment, task test for i386 Removed test WIP Runtime tests work Have a global set in one task and reacted to in another. Also test that local variables are preserved after a task switch. Removed new lines Increased line length Move the allocation of the bool above the task creation
2020-07-18 22:46:24 +01:00
const tty = @import("tty.zig");
const vga = @import("vga.zig");
const mem = @import("../../mem.zig");
const multiboot = @import("multiboot.zig");
2020-01-09 16:16:51 +00:00
const vmm = @import("../../vmm.zig");
2020-07-14 21:52:54 +01:00
const keyboard = @import("keyboard.zig");
2020-06-04 14:39:37 +01:00
const Serial = @import("../../serial.zig").Serial;
const panic = @import("../../panic.zig").panic;
2020-06-12 12:05:50 +01:00
const TTY = @import("../../tty.zig").TTY;
2020-07-14 21:52:54 +01:00
const Keyboard = @import("../../keyboard.zig").Keyboard;
2020-07-24 00:18:56 +01:00
const Task = @import("../../task.zig").Task;
const MemProfile = mem.MemProfile;
/// The type of a device.
pub const Device = pci.PciDeviceInfo;
Initial scheduler Fix TSS Also change to .{} syntax where appropriate. Added the SS segment Fixed spelling Refactoring GDT Multitasking working for now WIP scheduler Refactored Bitmap a bit WIP still Task switching working Handlers return the stack pointer that will be used to restore the tasks stack, normal handlers will return the same stack pointer it was called with where task switching will return the stack pointer of the next task and restore its state using the interrupt stub. Initial scheduler done Created a stage 2 init task Change u32 to usize Move Task to arch specific WIP WIP2 Removed esp from task, replaced with stack_pointer Removed the debug logs Fixed init task stack Change pickNextTask to pointer manipulation This allows less allocations so faster switching Temporary enable interrupts for some runtime tests PIT and RTC need interrupts enabled to run their runtime tests Renamed schedule => pickNextTask, comptime bitmap for pids not task init And some other stuff: No pub for the task anymore Use the leak detector allocator Fmt Fix unit tests And some other stuff :P PR review Moved Task out of arch and have the stack init in the arch file Mocking clean up Removed commented code Renamed createTask to scheduleTask where the user will have to provide a task to schedule Removed redundant pub in log runtime test Removed global allocator for scheduler Cleaner assembly in paging Fmt Added new Scheduler test mode Added new test mode to CI Removed one of the prints Added doc comment, task test for i386 Removed test WIP Runtime tests work Have a global set in one task and reacted to in another. Also test that local variables are preserved after a task switch. Removed new lines Increased line length Move the allocation of the bool above the task creation
2020-07-18 22:46:24 +01:00
/// The virtual end of the kernel code.
extern var KERNEL_VADDR_END: *u32;
Initial scheduler Fix TSS Also change to .{} syntax where appropriate. Added the SS segment Fixed spelling Refactoring GDT Multitasking working for now WIP scheduler Refactored Bitmap a bit WIP still Task switching working Handlers return the stack pointer that will be used to restore the tasks stack, normal handlers will return the same stack pointer it was called with where task switching will return the stack pointer of the next task and restore its state using the interrupt stub. Initial scheduler done Created a stage 2 init task Change u32 to usize Move Task to arch specific WIP WIP2 Removed esp from task, replaced with stack_pointer Removed the debug logs Fixed init task stack Change pickNextTask to pointer manipulation This allows less allocations so faster switching Temporary enable interrupts for some runtime tests PIT and RTC need interrupts enabled to run their runtime tests Renamed schedule => pickNextTask, comptime bitmap for pids not task init And some other stuff: No pub for the task anymore Use the leak detector allocator Fmt Fix unit tests And some other stuff :P PR review Moved Task out of arch and have the stack init in the arch file Mocking clean up Removed commented code Renamed createTask to scheduleTask where the user will have to provide a task to schedule Removed redundant pub in log runtime test Removed global allocator for scheduler Cleaner assembly in paging Fmt Added new Scheduler test mode Added new test mode to CI Removed one of the prints Added doc comment, task test for i386 Removed test WIP Runtime tests work Have a global set in one task and reacted to in another. Also test that local variables are preserved after a task switch. Removed new lines Increased line length Move the allocation of the bool above the task creation
2020-07-18 22:46:24 +01:00
/// The virtual start of the kernel code.
extern var KERNEL_VADDR_START: *u32;
Initial scheduler Fix TSS Also change to .{} syntax where appropriate. Added the SS segment Fixed spelling Refactoring GDT Multitasking working for now WIP scheduler Refactored Bitmap a bit WIP still Task switching working Handlers return the stack pointer that will be used to restore the tasks stack, normal handlers will return the same stack pointer it was called with where task switching will return the stack pointer of the next task and restore its state using the interrupt stub. Initial scheduler done Created a stage 2 init task Change u32 to usize Move Task to arch specific WIP WIP2 Removed esp from task, replaced with stack_pointer Removed the debug logs Fixed init task stack Change pickNextTask to pointer manipulation This allows less allocations so faster switching Temporary enable interrupts for some runtime tests PIT and RTC need interrupts enabled to run their runtime tests Renamed schedule => pickNextTask, comptime bitmap for pids not task init And some other stuff: No pub for the task anymore Use the leak detector allocator Fmt Fix unit tests And some other stuff :P PR review Moved Task out of arch and have the stack init in the arch file Mocking clean up Removed commented code Renamed createTask to scheduleTask where the user will have to provide a task to schedule Removed redundant pub in log runtime test Removed global allocator for scheduler Cleaner assembly in paging Fmt Added new Scheduler test mode Added new test mode to CI Removed one of the prints Added doc comment, task test for i386 Removed test WIP Runtime tests work Have a global set in one task and reacted to in another. Also test that local variables are preserved after a task switch. Removed new lines Increased line length Move the allocation of the bool above the task creation
2020-07-18 22:46:24 +01:00
/// The physical end of the kernel code.
extern var KERNEL_PHYSADDR_END: *u32;
Initial scheduler Fix TSS Also change to .{} syntax where appropriate. Added the SS segment Fixed spelling Refactoring GDT Multitasking working for now WIP scheduler Refactored Bitmap a bit WIP still Task switching working Handlers return the stack pointer that will be used to restore the tasks stack, normal handlers will return the same stack pointer it was called with where task switching will return the stack pointer of the next task and restore its state using the interrupt stub. Initial scheduler done Created a stage 2 init task Change u32 to usize Move Task to arch specific WIP WIP2 Removed esp from task, replaced with stack_pointer Removed the debug logs Fixed init task stack Change pickNextTask to pointer manipulation This allows less allocations so faster switching Temporary enable interrupts for some runtime tests PIT and RTC need interrupts enabled to run their runtime tests Renamed schedule => pickNextTask, comptime bitmap for pids not task init And some other stuff: No pub for the task anymore Use the leak detector allocator Fmt Fix unit tests And some other stuff :P PR review Moved Task out of arch and have the stack init in the arch file Mocking clean up Removed commented code Renamed createTask to scheduleTask where the user will have to provide a task to schedule Removed redundant pub in log runtime test Removed global allocator for scheduler Cleaner assembly in paging Fmt Added new Scheduler test mode Added new test mode to CI Removed one of the prints Added doc comment, task test for i386 Removed test WIP Runtime tests work Have a global set in one task and reacted to in another. Also test that local variables are preserved after a task switch. Removed new lines Increased line length Move the allocation of the bool above the task creation
2020-07-18 22:46:24 +01:00
/// The physical start of the kernel code.
extern var KERNEL_PHYSADDR_START: *u32;
Initial scheduler Fix TSS Also change to .{} syntax where appropriate. Added the SS segment Fixed spelling Refactoring GDT Multitasking working for now WIP scheduler Refactored Bitmap a bit WIP still Task switching working Handlers return the stack pointer that will be used to restore the tasks stack, normal handlers will return the same stack pointer it was called with where task switching will return the stack pointer of the next task and restore its state using the interrupt stub. Initial scheduler done Created a stage 2 init task Change u32 to usize Move Task to arch specific WIP WIP2 Removed esp from task, replaced with stack_pointer Removed the debug logs Fixed init task stack Change pickNextTask to pointer manipulation This allows less allocations so faster switching Temporary enable interrupts for some runtime tests PIT and RTC need interrupts enabled to run their runtime tests Renamed schedule => pickNextTask, comptime bitmap for pids not task init And some other stuff: No pub for the task anymore Use the leak detector allocator Fmt Fix unit tests And some other stuff :P PR review Moved Task out of arch and have the stack init in the arch file Mocking clean up Removed commented code Renamed createTask to scheduleTask where the user will have to provide a task to schedule Removed redundant pub in log runtime test Removed global allocator for scheduler Cleaner assembly in paging Fmt Added new Scheduler test mode Added new test mode to CI Removed one of the prints Added doc comment, task test for i386 Removed test WIP Runtime tests work Have a global set in one task and reacted to in another. Also test that local variables are preserved after a task switch. Removed new lines Increased line length Move the allocation of the bool above the task creation
2020-07-18 22:46:24 +01:00
/// The boot-time offset that the virtual addresses are from the physical addresses.
extern var KERNEL_ADDR_OFFSET: *u32;
Initial scheduler Fix TSS Also change to .{} syntax where appropriate. Added the SS segment Fixed spelling Refactoring GDT Multitasking working for now WIP scheduler Refactored Bitmap a bit WIP still Task switching working Handlers return the stack pointer that will be used to restore the tasks stack, normal handlers will return the same stack pointer it was called with where task switching will return the stack pointer of the next task and restore its state using the interrupt stub. Initial scheduler done Created a stage 2 init task Change u32 to usize Move Task to arch specific WIP WIP2 Removed esp from task, replaced with stack_pointer Removed the debug logs Fixed init task stack Change pickNextTask to pointer manipulation This allows less allocations so faster switching Temporary enable interrupts for some runtime tests PIT and RTC need interrupts enabled to run their runtime tests Renamed schedule => pickNextTask, comptime bitmap for pids not task init And some other stuff: No pub for the task anymore Use the leak detector allocator Fmt Fix unit tests And some other stuff :P PR review Moved Task out of arch and have the stack init in the arch file Mocking clean up Removed commented code Renamed createTask to scheduleTask where the user will have to provide a task to schedule Removed redundant pub in log runtime test Removed global allocator for scheduler Cleaner assembly in paging Fmt Added new Scheduler test mode Added new test mode to CI Removed one of the prints Added doc comment, task test for i386 Removed test WIP Runtime tests work Have a global set in one task and reacted to in another. Also test that local variables are preserved after a task switch. Removed new lines Increased line length Move the allocation of the bool above the task creation
2020-07-18 22:46:24 +01:00
/// The virtual address of the top limit of the stack.
extern var KERNEL_STACK_START: *u32;
/// The virtual address of the base of the stack.
extern var KERNEL_STACK_END: *u32;
/// The interrupt context that is given to a interrupt handler. It contains most of the registers
/// and the interrupt number and error code (if there is one).
Initial scheduler Fix TSS Also change to .{} syntax where appropriate. Added the SS segment Fixed spelling Refactoring GDT Multitasking working for now WIP scheduler Refactored Bitmap a bit WIP still Task switching working Handlers return the stack pointer that will be used to restore the tasks stack, normal handlers will return the same stack pointer it was called with where task switching will return the stack pointer of the next task and restore its state using the interrupt stub. Initial scheduler done Created a stage 2 init task Change u32 to usize Move Task to arch specific WIP WIP2 Removed esp from task, replaced with stack_pointer Removed the debug logs Fixed init task stack Change pickNextTask to pointer manipulation This allows less allocations so faster switching Temporary enable interrupts for some runtime tests PIT and RTC need interrupts enabled to run their runtime tests Renamed schedule => pickNextTask, comptime bitmap for pids not task init And some other stuff: No pub for the task anymore Use the leak detector allocator Fmt Fix unit tests And some other stuff :P PR review Moved Task out of arch and have the stack init in the arch file Mocking clean up Removed commented code Renamed createTask to scheduleTask where the user will have to provide a task to schedule Removed redundant pub in log runtime test Removed global allocator for scheduler Cleaner assembly in paging Fmt Added new Scheduler test mode Added new test mode to CI Removed one of the prints Added doc comment, task test for i386 Removed test WIP Runtime tests work Have a global set in one task and reacted to in another. Also test that local variables are preserved after a task switch. Removed new lines Increased line length Move the allocation of the bool above the task creation
2020-07-18 22:46:24 +01:00
pub const CpuState = packed struct {
2020-07-24 00:18:56 +01:00
// Page directory
cr3: usize,
// Extra segments
gs: u32,
fs: u32,
es: u32,
ds: u32,
// Destination, source, base pointer
edi: u32,
esi: u32,
ebp: u32,
esp: u32,
// General registers
ebx: u32,
edx: u32,
ecx: u32,
eax: u32,
// Interrupt number and error code
int_num: u32,
error_code: u32,
// Instruction pointer, code segment and flags
eip: u32,
cs: u32,
eflags: u32,
user_esp: u32,
Initial scheduler Fix TSS Also change to .{} syntax where appropriate. Added the SS segment Fixed spelling Refactoring GDT Multitasking working for now WIP scheduler Refactored Bitmap a bit WIP still Task switching working Handlers return the stack pointer that will be used to restore the tasks stack, normal handlers will return the same stack pointer it was called with where task switching will return the stack pointer of the next task and restore its state using the interrupt stub. Initial scheduler done Created a stage 2 init task Change u32 to usize Move Task to arch specific WIP WIP2 Removed esp from task, replaced with stack_pointer Removed the debug logs Fixed init task stack Change pickNextTask to pointer manipulation This allows less allocations so faster switching Temporary enable interrupts for some runtime tests PIT and RTC need interrupts enabled to run their runtime tests Renamed schedule => pickNextTask, comptime bitmap for pids not task init And some other stuff: No pub for the task anymore Use the leak detector allocator Fmt Fix unit tests And some other stuff :P PR review Moved Task out of arch and have the stack init in the arch file Mocking clean up Removed commented code Renamed createTask to scheduleTask where the user will have to provide a task to schedule Removed redundant pub in log runtime test Removed global allocator for scheduler Cleaner assembly in paging Fmt Added new Scheduler test mode Added new test mode to CI Removed one of the prints Added doc comment, task test for i386 Removed test WIP Runtime tests work Have a global set in one task and reacted to in another. Also test that local variables are preserved after a task switch. Removed new lines Increased line length Move the allocation of the bool above the task creation
2020-07-18 22:46:24 +01:00
user_ss: u32,
};
/// x86's boot payload is the multiboot info passed by grub
pub const BootPayload = *multiboot.multiboot_info_t;
2020-01-09 16:16:51 +00:00
/// The type of the payload passed to a virtual memory mapper.
/// For x86 it's the page directory that should be mapped.
pub const VmmPayload = *paging.Directory;
/// The payload used in the kernel virtual memory manager.
/// For x86 it's the kernel's page directory.
pub const KERNEL_VMM_PAYLOAD = &paging.kernel_directory;
/// The architecture's virtual memory mapper.
/// For x86, it simply forwards the calls to the paging subsystem.
pub const VMM_MAPPER: vmm.Mapper(VmmPayload) = vmm.Mapper(VmmPayload){ .mapFn = paging.map, .unmapFn = paging.unmap };
2019-09-09 23:38:06 +01:00
/// The size of each allocatable block of memory, normally set to the page size.
2020-05-12 14:08:29 +01:00
pub const MEMORY_BLOCK_SIZE: usize = paging.PAGE_SIZE_4KB;
2019-09-09 23:38:06 +01:00
///
/// Assembly that reads data from a given port and returns its value.
///
/// Arguments:
/// IN comptime Type: type - The type of the data. This can only be u8, u16 or u32.
/// IN port: u16 - The port to read data from.
///
/// Return: Type
/// The data that the port returns.
///
pub fn in(comptime Type: type, port: u16) Type {
return switch (Type) {
u8 => asm volatile ("inb %[port], %[result]"
: [result] "={al}" (-> Type)
: [port] "N{dx}" (port)
),
u16 => asm volatile ("inw %[port], %[result]"
: [result] "={ax}" (-> Type)
: [port] "N{dx}" (port)
),
u32 => asm volatile ("inl %[port], %[result]"
: [result] "={eax}" (-> Type)
: [port] "N{dx}" (port)
),
else => @compileError("Invalid data type. Only u8, u16 or u32, found: " ++ @typeName(Type)),
};
}
///
/// Assembly to write to a given port with a give type of data.
///
/// Arguments:
/// IN port: u16 - The port to write to.
/// IN data: anytype - The data that will be sent This must be a u8, u16 or u32 type.
///
pub fn out(port: u16, data: anytype) void {
switch (@TypeOf(data)) {
u8 => asm volatile ("outb %[data], %[port]"
:
: [port] "{dx}" (port),
[data] "{al}" (data)
),
u16 => asm volatile ("outw %[data], %[port]"
:
: [port] "{dx}" (port),
[data] "{ax}" (data)
),
u32 => asm volatile ("outl %[data], %[port]"
:
: [port] "{dx}" (port),
[data] "{eax}" (data)
),
else => @compileError("Invalid data type. Only u8, u16 or u32, found: " ++ @typeName(@TypeOf(data))),
}
}
///
/// Force the CPU to wait for an I/O operation to compete. Use port 0x80 as this is unused.
///
pub fn ioWait() void {
out(0x80, @as(u8, 0));
}
///
/// Load the GDT and refreshing the code segment with the code segment offset of the kernel as we
/// are still in kernel land. Also loads the kernel data segment into all the other segment
/// registers.
///
/// Arguments:
/// IN gdt_ptr: *gdt.GdtPtr - The address to the GDT.
///
pub fn lgdt(gdt_ptr: *const gdt.GdtPtr) void {
// Load the GDT into the CPU
asm volatile ("lgdt (%%eax)"
:
: [gdt_ptr] "{eax}" (gdt_ptr)
);
// Load the kernel data segment, index into the GDT
asm volatile ("mov %%bx, %%ds"
:
: [KERNEL_DATA_OFFSET] "{bx}" (gdt.KERNEL_DATA_OFFSET)
);
asm volatile ("mov %%bx, %%es");
asm volatile ("mov %%bx, %%fs");
asm volatile ("mov %%bx, %%gs");
asm volatile ("mov %%bx, %%ss");
// Load the kernel code segment into the CS register
asm volatile (
\\ljmp $0x08, $1f
\\1:
);
}
///
/// Get the previously loaded GDT from the CPU.
///
/// Return: gdt.GdtPtr
/// The previously loaded GDT from the CPU.
///
pub fn sgdt() gdt.GdtPtr {
2019-09-17 18:24:27 +01:00
var gdt_ptr = gdt.GdtPtr{ .limit = 0, .base = 0 };
asm volatile ("sgdt %[tab]"
: [tab] "=m" (gdt_ptr)
);
return gdt_ptr;
}
///
/// Tell the CPU where the TSS is located in the GDT.
///
/// Arguments:
/// IN offset: u16 - The offset in the GDT where the TSS segment is located.
///
pub fn ltr(offset: u16) void {
asm volatile ("ltr %%ax"
:
: [offset] "{ax}" (offset)
);
}
///
/// Load the IDT into the CPU.
///
/// Arguments:
/// IN idt_ptr: *const idt.IdtPtr - The address of the iDT.
///
pub fn lidt(idt_ptr: *const idt.IdtPtr) void {
asm volatile ("lidt (%%eax)"
:
: [idt_ptr] "{eax}" (idt_ptr)
);
}
2019-09-17 18:24:27 +01:00
///
/// Get the previously loaded IDT from the CPU.
///
/// Return: idt.IdtPtr
/// The previously loaded IDT from the CPU.
///
pub fn sidt() idt.IdtPtr {
var idt_ptr = idt.IdtPtr{ .limit = 0, .base = 0 };
asm volatile ("sidt %[tab]"
: [tab] "=m" (idt_ptr)
);
return idt_ptr;
}
///
/// Enable interrupts.
///
pub fn enableInterrupts() void {
asm volatile ("sti");
}
///
/// Disable interrupts.
///
pub fn disableInterrupts() void {
asm volatile ("cli");
}
///
/// Halt the CPU, but interrupts will still be called.
///
pub fn halt() void {
asm volatile ("hlt");
}
///
/// Wait the kernel but still can handle interrupts.
///
pub fn spinWait() noreturn {
Initial scheduler Fix TSS Also change to .{} syntax where appropriate. Added the SS segment Fixed spelling Refactoring GDT Multitasking working for now WIP scheduler Refactored Bitmap a bit WIP still Task switching working Handlers return the stack pointer that will be used to restore the tasks stack, normal handlers will return the same stack pointer it was called with where task switching will return the stack pointer of the next task and restore its state using the interrupt stub. Initial scheduler done Created a stage 2 init task Change u32 to usize Move Task to arch specific WIP WIP2 Removed esp from task, replaced with stack_pointer Removed the debug logs Fixed init task stack Change pickNextTask to pointer manipulation This allows less allocations so faster switching Temporary enable interrupts for some runtime tests PIT and RTC need interrupts enabled to run their runtime tests Renamed schedule => pickNextTask, comptime bitmap for pids not task init And some other stuff: No pub for the task anymore Use the leak detector allocator Fmt Fix unit tests And some other stuff :P PR review Moved Task out of arch and have the stack init in the arch file Mocking clean up Removed commented code Renamed createTask to scheduleTask where the user will have to provide a task to schedule Removed redundant pub in log runtime test Removed global allocator for scheduler Cleaner assembly in paging Fmt Added new Scheduler test mode Added new test mode to CI Removed one of the prints Added doc comment, task test for i386 Removed test WIP Runtime tests work Have a global set in one task and reacted to in another. Also test that local variables are preserved after a task switch. Removed new lines Increased line length Move the allocation of the bool above the task creation
2020-07-18 22:46:24 +01:00
enableInterrupts();
while (true) {
halt();
}
}
///
/// Halt the kernel. No interrupts will be handled.
///
pub fn haltNoInterrupts() noreturn {
while (true) {
disableInterrupts();
halt();
}
2019-06-22 10:00:57 +01:00
}
2019-07-01 21:48:04 +01:00
2020-06-04 14:39:37 +01:00
///
/// Write a byte to serial port com1. Used by the serial initialiser
///
/// Arguments:
/// IN byte: u8 - The byte to write
///
fn writeSerialCom1(byte: u8) void {
serial.write(byte, serial.Port.COM1);
}
///
/// Initialise serial communication using port COM1 and construct a Serial instance
///
2020-06-09 13:47:06 +01:00
/// Arguments:
/// IN boot_payload: arch.BootPayload - The payload passed at boot. Not currently used by x86
///
2020-06-04 14:39:37 +01:00
/// Return: serial.Serial
/// The Serial instance constructed with the function used to write bytes
///
2020-06-09 13:47:06 +01:00
pub fn initSerial(boot_payload: BootPayload) Serial {
2020-06-04 14:39:37 +01:00
serial.init(serial.DEFAULT_BAUDRATE, serial.Port.COM1) catch |e| {
panic(@errorReturnTrace(), "Failed to initialise serial: {}", .{e});
};
return Serial{
.write = writeSerialCom1,
};
}
2020-06-12 12:05:50 +01:00
///
/// Initialise the TTY and construct a TTY instance
///
/// Arguments:
/// IN boot_payload: BootPayload - The payload passed to the kernel on boot
///
/// Return: tty.TTY
/// The TTY instance constructed with the information required by the rest of the kernel
///
pub fn initTTY(boot_payload: BootPayload) TTY {
return .{
.print = tty.writeString,
.setCursor = tty.setCursor,
.cols = vga.WIDTH,
.rows = vga.HEIGHT,
.clear = tty.clearScreen,
};
}
///
/// Initialise the system's memory. Populates a memory profile with boot modules from grub, the amount of available memory, the reserved regions of virtual and physical memory as well as the start and end of the kernel code
///
/// Arguments:
/// IN mb_info: *multiboot.multiboot_info_t - The multiboot info passed by grub
///
/// Return: mem.MemProfile
/// The constructed memory profile
///
Initial scheduler Fix TSS Also change to .{} syntax where appropriate. Added the SS segment Fixed spelling Refactoring GDT Multitasking working for now WIP scheduler Refactored Bitmap a bit WIP still Task switching working Handlers return the stack pointer that will be used to restore the tasks stack, normal handlers will return the same stack pointer it was called with where task switching will return the stack pointer of the next task and restore its state using the interrupt stub. Initial scheduler done Created a stage 2 init task Change u32 to usize Move Task to arch specific WIP WIP2 Removed esp from task, replaced with stack_pointer Removed the debug logs Fixed init task stack Change pickNextTask to pointer manipulation This allows less allocations so faster switching Temporary enable interrupts for some runtime tests PIT and RTC need interrupts enabled to run their runtime tests Renamed schedule => pickNextTask, comptime bitmap for pids not task init And some other stuff: No pub for the task anymore Use the leak detector allocator Fmt Fix unit tests And some other stuff :P PR review Moved Task out of arch and have the stack init in the arch file Mocking clean up Removed commented code Renamed createTask to scheduleTask where the user will have to provide a task to schedule Removed redundant pub in log runtime test Removed global allocator for scheduler Cleaner assembly in paging Fmt Added new Scheduler test mode Added new test mode to CI Removed one of the prints Added doc comment, task test for i386 Removed test WIP Runtime tests work Have a global set in one task and reacted to in another. Also test that local variables are preserved after a task switch. Removed new lines Increased line length Move the allocation of the bool above the task creation
2020-07-18 22:46:24 +01:00
/// Error: Allocator.Error
/// Allocator.Error.OutOfMemory - There wasn't enough memory in the allocated created to populate the memory profile, consider increasing mem.FIXED_ALLOC_SIZE
///
Initial scheduler Fix TSS Also change to .{} syntax where appropriate. Added the SS segment Fixed spelling Refactoring GDT Multitasking working for now WIP scheduler Refactored Bitmap a bit WIP still Task switching working Handlers return the stack pointer that will be used to restore the tasks stack, normal handlers will return the same stack pointer it was called with where task switching will return the stack pointer of the next task and restore its state using the interrupt stub. Initial scheduler done Created a stage 2 init task Change u32 to usize Move Task to arch specific WIP WIP2 Removed esp from task, replaced with stack_pointer Removed the debug logs Fixed init task stack Change pickNextTask to pointer manipulation This allows less allocations so faster switching Temporary enable interrupts for some runtime tests PIT and RTC need interrupts enabled to run their runtime tests Renamed schedule => pickNextTask, comptime bitmap for pids not task init And some other stuff: No pub for the task anymore Use the leak detector allocator Fmt Fix unit tests And some other stuff :P PR review Moved Task out of arch and have the stack init in the arch file Mocking clean up Removed commented code Renamed createTask to scheduleTask where the user will have to provide a task to schedule Removed redundant pub in log runtime test Removed global allocator for scheduler Cleaner assembly in paging Fmt Added new Scheduler test mode Added new test mode to CI Removed one of the prints Added doc comment, task test for i386 Removed test WIP Runtime tests work Have a global set in one task and reacted to in another. Also test that local variables are preserved after a task switch. Removed new lines Increased line length Move the allocation of the bool above the task creation
2020-07-18 22:46:24 +01:00
pub fn initMem(mb_info: BootPayload) Allocator.Error!MemProfile {
2020-08-23 14:32:32 +01:00
log.info("Init\n", .{});
defer log.info("Done\n", .{});
log.debug("KERNEL_ADDR_OFFSET: 0x{X}\n", .{@ptrToInt(&KERNEL_ADDR_OFFSET)});
log.debug("KERNEL_STACK_START: 0x{X}\n", .{@ptrToInt(&KERNEL_STACK_START)});
log.debug("KERNEL_STACK_END: 0x{X}\n", .{@ptrToInt(&KERNEL_STACK_END)});
log.debug("KERNEL_VADDR_START: 0x{X}\n", .{@ptrToInt(&KERNEL_VADDR_START)});
log.debug("KERNEL_VADDR_END: 0x{X}\n", .{@ptrToInt(&KERNEL_VADDR_END)});
log.debug("KERNEL_PHYSADDR_START: 0x{X}\n", .{@ptrToInt(&KERNEL_PHYSADDR_START)});
log.debug("KERNEL_PHYSADDR_END: 0x{X}\n", .{@ptrToInt(&KERNEL_PHYSADDR_END)});
Initial scheduler Fix TSS Also change to .{} syntax where appropriate. Added the SS segment Fixed spelling Refactoring GDT Multitasking working for now WIP scheduler Refactored Bitmap a bit WIP still Task switching working Handlers return the stack pointer that will be used to restore the tasks stack, normal handlers will return the same stack pointer it was called with where task switching will return the stack pointer of the next task and restore its state using the interrupt stub. Initial scheduler done Created a stage 2 init task Change u32 to usize Move Task to arch specific WIP WIP2 Removed esp from task, replaced with stack_pointer Removed the debug logs Fixed init task stack Change pickNextTask to pointer manipulation This allows less allocations so faster switching Temporary enable interrupts for some runtime tests PIT and RTC need interrupts enabled to run their runtime tests Renamed schedule => pickNextTask, comptime bitmap for pids not task init And some other stuff: No pub for the task anymore Use the leak detector allocator Fmt Fix unit tests And some other stuff :P PR review Moved Task out of arch and have the stack init in the arch file Mocking clean up Removed commented code Renamed createTask to scheduleTask where the user will have to provide a task to schedule Removed redundant pub in log runtime test Removed global allocator for scheduler Cleaner assembly in paging Fmt Added new Scheduler test mode Added new test mode to CI Removed one of the prints Added doc comment, task test for i386 Removed test WIP Runtime tests work Have a global set in one task and reacted to in another. Also test that local variables are preserved after a task switch. Removed new lines Increased line length Move the allocation of the bool above the task creation
2020-07-18 22:46:24 +01:00
const mods_count = mb_info.mods_count;
mem.ADDR_OFFSET = @ptrToInt(&KERNEL_ADDR_OFFSET);
const mmap_addr = mb_info.mmap_addr;
const num_mmap_entries = mb_info.mmap_length / @sizeOf(multiboot.multiboot_memory_map_t);
const allocator = &mem.fixed_buffer_allocator.allocator;
var reserved_physical_mem = std.ArrayList(mem.Range).init(allocator);
var reserved_virtual_mem = std.ArrayList(mem.Map).init(allocator);
const mem_map = @intToPtr([*]multiboot.multiboot_memory_map_t, mmap_addr)[0..num_mmap_entries];
// Reserve the unavailable sections from the multiboot memory map
for (mem_map) |entry| {
if (entry.@"type" != multiboot.MULTIBOOT_MEMORY_AVAILABLE) {
// If addr + len is greater than maxInt(usize) just ignore whatever comes after maxInt(usize) since it can't be addressed anyway
const end: usize = if (entry.addr > std.math.maxInt(usize) - entry.len) std.math.maxInt(usize) else @intCast(usize, entry.addr + entry.len);
try reserved_physical_mem.append(.{
.start = @intCast(usize, entry.addr),
.end = end,
});
}
}
Initial scheduler Fix TSS Also change to .{} syntax where appropriate. Added the SS segment Fixed spelling Refactoring GDT Multitasking working for now WIP scheduler Refactored Bitmap a bit WIP still Task switching working Handlers return the stack pointer that will be used to restore the tasks stack, normal handlers will return the same stack pointer it was called with where task switching will return the stack pointer of the next task and restore its state using the interrupt stub. Initial scheduler done Created a stage 2 init task Change u32 to usize Move Task to arch specific WIP WIP2 Removed esp from task, replaced with stack_pointer Removed the debug logs Fixed init task stack Change pickNextTask to pointer manipulation This allows less allocations so faster switching Temporary enable interrupts for some runtime tests PIT and RTC need interrupts enabled to run their runtime tests Renamed schedule => pickNextTask, comptime bitmap for pids not task init And some other stuff: No pub for the task anymore Use the leak detector allocator Fmt Fix unit tests And some other stuff :P PR review Moved Task out of arch and have the stack init in the arch file Mocking clean up Removed commented code Renamed createTask to scheduleTask where the user will have to provide a task to schedule Removed redundant pub in log runtime test Removed global allocator for scheduler Cleaner assembly in paging Fmt Added new Scheduler test mode Added new test mode to CI Removed one of the prints Added doc comment, task test for i386 Removed test WIP Runtime tests work Have a global set in one task and reacted to in another. Also test that local variables are preserved after a task switch. Removed new lines Increased line length Move the allocation of the bool above the task creation
2020-07-18 22:46:24 +01:00
2020-08-23 19:48:10 +01:00
// Map the kernel code
const kernel_virt = mem.Range{
.start = @ptrToInt(&KERNEL_VADDR_START),
.end = @ptrToInt(&KERNEL_STACK_START),
};
const kernel_phy = mem.Range{
.start = mem.virtToPhys(kernel_virt.start),
.end = mem.virtToPhys(kernel_virt.end),
};
try reserved_virtual_mem.append(.{
.virtual = kernel_virt,
.physical = kernel_phy,
});
// Map the multiboot info struct itself
const mb_region = mem.Range{
.start = @ptrToInt(mb_info),
.end = @ptrToInt(mb_info) + @sizeOf(multiboot.multiboot_info_t),
};
const mb_physical = mem.Range{
.start = mem.virtToPhys(mb_region.start),
.end = mem.virtToPhys(mb_region.end),
};
try reserved_virtual_mem.append(.{
.virtual = mb_region,
.physical = mb_physical,
});
// Map the tty buffer
const tty_addr = mem.virtToPhys(tty.getVideoBufferAddress());
const tty_region = mem.Range{
.start = tty_addr,
.end = tty_addr + 32 * 1024,
};
try reserved_virtual_mem.append(.{
.physical = tty_region,
.virtual = .{
.start = mem.physToVirt(tty_region.start),
.end = mem.physToVirt(tty_region.end),
},
});
// Map the boot modules
const boot_modules = @intToPtr([*]multiboot.multiboot_mod_list, mem.physToVirt(mb_info.mods_addr))[0..mods_count];
var modules = std.ArrayList(mem.Module).init(allocator);
for (boot_modules) |module| {
const virtual = mem.Range{
.start = mem.physToVirt(module.mod_start),
.end = mem.physToVirt(module.mod_end),
};
const physical = mem.Range{
.start = module.mod_start,
.end = module.mod_end,
};
try modules.append(.{
.region = virtual,
.name = std.mem.span(mem.physToVirt(@intToPtr([*:0]u8, module.cmdline))),
});
try reserved_virtual_mem.append(.{
.physical = physical,
.virtual = virtual,
});
}
// Map the kernel stack
const kernel_stack_virt = mem.Range{
.start = @ptrToInt(&KERNEL_STACK_START),
.end = @ptrToInt(&KERNEL_STACK_END),
};
const kernel_stack_phy = mem.Range{
.start = mem.virtToPhys(kernel_stack_virt.start),
.end = mem.virtToPhys(kernel_stack_virt.end),
};
try reserved_virtual_mem.append(.{
.virtual = kernel_stack_virt,
.physical = kernel_stack_phy,
});
return MemProfile{
.vaddr_end = @ptrCast([*]u8, &KERNEL_VADDR_END),
.vaddr_start = @ptrCast([*]u8, &KERNEL_VADDR_START),
.physaddr_end = @ptrCast([*]u8, &KERNEL_PHYSADDR_END),
.physaddr_start = @ptrCast([*]u8, &KERNEL_PHYSADDR_START),
// Total memory available including the initial 1MiB that grub doesn't include
.mem_kb = mb_info.mem_upper + mb_info.mem_lower + 1024,
.modules = modules.items,
.physical_reserved = reserved_physical_mem.items,
.virtual_reserved = reserved_virtual_mem.items,
.fixed_allocator = mem.fixed_buffer_allocator,
};
}
2020-07-14 21:52:54 +01:00
///
/// Initialise the keyboard that may depend on the chipset or architecture in general.
/// x86 initialises the keyboard connected to the PS/2 port
///
/// Arguments:
/// IN allocator: *std.mem.Allocator - The allocator to use if necessary
///
/// Return: *Keyboard
/// The initialised PS/2 keyboard
///
/// Error: std.mem.Allocator.Error
/// OutOfMemory - There wasn't enough memory to allocate what was needed
///
pub fn initKeyboard(allocator: *Allocator) Allocator.Error!*Keyboard {
return keyboard.init(allocator);
}
Initial scheduler Fix TSS Also change to .{} syntax where appropriate. Added the SS segment Fixed spelling Refactoring GDT Multitasking working for now WIP scheduler Refactored Bitmap a bit WIP still Task switching working Handlers return the stack pointer that will be used to restore the tasks stack, normal handlers will return the same stack pointer it was called with where task switching will return the stack pointer of the next task and restore its state using the interrupt stub. Initial scheduler done Created a stage 2 init task Change u32 to usize Move Task to arch specific WIP WIP2 Removed esp from task, replaced with stack_pointer Removed the debug logs Fixed init task stack Change pickNextTask to pointer manipulation This allows less allocations so faster switching Temporary enable interrupts for some runtime tests PIT and RTC need interrupts enabled to run their runtime tests Renamed schedule => pickNextTask, comptime bitmap for pids not task init And some other stuff: No pub for the task anymore Use the leak detector allocator Fmt Fix unit tests And some other stuff :P PR review Moved Task out of arch and have the stack init in the arch file Mocking clean up Removed commented code Renamed createTask to scheduleTask where the user will have to provide a task to schedule Removed redundant pub in log runtime test Removed global allocator for scheduler Cleaner assembly in paging Fmt Added new Scheduler test mode Added new test mode to CI Removed one of the prints Added doc comment, task test for i386 Removed test WIP Runtime tests work Have a global set in one task and reacted to in another. Also test that local variables are preserved after a task switch. Removed new lines Increased line length Move the allocation of the bool above the task creation
2020-07-18 22:46:24 +01:00
///
2020-07-24 00:18:56 +01:00
/// Initialise a stack used for creating a task.
Initial scheduler Fix TSS Also change to .{} syntax where appropriate. Added the SS segment Fixed spelling Refactoring GDT Multitasking working for now WIP scheduler Refactored Bitmap a bit WIP still Task switching working Handlers return the stack pointer that will be used to restore the tasks stack, normal handlers will return the same stack pointer it was called with where task switching will return the stack pointer of the next task and restore its state using the interrupt stub. Initial scheduler done Created a stage 2 init task Change u32 to usize Move Task to arch specific WIP WIP2 Removed esp from task, replaced with stack_pointer Removed the debug logs Fixed init task stack Change pickNextTask to pointer manipulation This allows less allocations so faster switching Temporary enable interrupts for some runtime tests PIT and RTC need interrupts enabled to run their runtime tests Renamed schedule => pickNextTask, comptime bitmap for pids not task init And some other stuff: No pub for the task anymore Use the leak detector allocator Fmt Fix unit tests And some other stuff :P PR review Moved Task out of arch and have the stack init in the arch file Mocking clean up Removed commented code Renamed createTask to scheduleTask where the user will have to provide a task to schedule Removed redundant pub in log runtime test Removed global allocator for scheduler Cleaner assembly in paging Fmt Added new Scheduler test mode Added new test mode to CI Removed one of the prints Added doc comment, task test for i386 Removed test WIP Runtime tests work Have a global set in one task and reacted to in another. Also test that local variables are preserved after a task switch. Removed new lines Increased line length Move the allocation of the bool above the task creation
2020-07-18 22:46:24 +01:00
/// Currently only support fn () noreturn functions for the entry point.
///
/// Arguments:
2020-07-24 00:18:56 +01:00
/// IN task: *Task - The task to be initialised. The function will only modify whatever
/// is required by the architecture. In the case of x86, it will put
/// the initial CpuState on the kernel stack.
Initial scheduler Fix TSS Also change to .{} syntax where appropriate. Added the SS segment Fixed spelling Refactoring GDT Multitasking working for now WIP scheduler Refactored Bitmap a bit WIP still Task switching working Handlers return the stack pointer that will be used to restore the tasks stack, normal handlers will return the same stack pointer it was called with where task switching will return the stack pointer of the next task and restore its state using the interrupt stub. Initial scheduler done Created a stage 2 init task Change u32 to usize Move Task to arch specific WIP WIP2 Removed esp from task, replaced with stack_pointer Removed the debug logs Fixed init task stack Change pickNextTask to pointer manipulation This allows less allocations so faster switching Temporary enable interrupts for some runtime tests PIT and RTC need interrupts enabled to run their runtime tests Renamed schedule => pickNextTask, comptime bitmap for pids not task init And some other stuff: No pub for the task anymore Use the leak detector allocator Fmt Fix unit tests And some other stuff :P PR review Moved Task out of arch and have the stack init in the arch file Mocking clean up Removed commented code Renamed createTask to scheduleTask where the user will have to provide a task to schedule Removed redundant pub in log runtime test Removed global allocator for scheduler Cleaner assembly in paging Fmt Added new Scheduler test mode Added new test mode to CI Removed one of the prints Added doc comment, task test for i386 Removed test WIP Runtime tests work Have a global set in one task and reacted to in another. Also test that local variables are preserved after a task switch. Removed new lines Increased line length Move the allocation of the bool above the task creation
2020-07-18 22:46:24 +01:00
/// IN entry_point: usize - The pointer to the entry point of the function. Functions only
/// supported is fn () noreturn
/// IN allocator: *Allocator - The allocator use for allocating a stack.
///
/// Error: Allocator.Error
/// OutOfMemory - Unable to allocate space for the stack.
///
2020-07-24 00:18:56 +01:00
pub fn initTask(task: *Task, entry_point: usize, allocator: *Allocator) Allocator.Error!void {
const data_offset = if (task.kernel) gdt.KERNEL_DATA_OFFSET else gdt.USER_DATA_OFFSET | 0b11;
// Setting the bottom two bits of the code offset designates that this is a ring 3 task
const code_offset = if (task.kernel) gdt.KERNEL_CODE_OFFSET else gdt.USER_CODE_OFFSET | 0b11;
// Ring switches push and pop two extra values on interrupt: user_esp and user_ss
const kernel_stack_bottom = if (task.kernel) task.kernel_stack.len - 18 else task.kernel_stack.len - 20;
var stack = &task.kernel_stack;
Initial scheduler Fix TSS Also change to .{} syntax where appropriate. Added the SS segment Fixed spelling Refactoring GDT Multitasking working for now WIP scheduler Refactored Bitmap a bit WIP still Task switching working Handlers return the stack pointer that will be used to restore the tasks stack, normal handlers will return the same stack pointer it was called with where task switching will return the stack pointer of the next task and restore its state using the interrupt stub. Initial scheduler done Created a stage 2 init task Change u32 to usize Move Task to arch specific WIP WIP2 Removed esp from task, replaced with stack_pointer Removed the debug logs Fixed init task stack Change pickNextTask to pointer manipulation This allows less allocations so faster switching Temporary enable interrupts for some runtime tests PIT and RTC need interrupts enabled to run their runtime tests Renamed schedule => pickNextTask, comptime bitmap for pids not task init And some other stuff: No pub for the task anymore Use the leak detector allocator Fmt Fix unit tests And some other stuff :P PR review Moved Task out of arch and have the stack init in the arch file Mocking clean up Removed commented code Renamed createTask to scheduleTask where the user will have to provide a task to schedule Removed redundant pub in log runtime test Removed global allocator for scheduler Cleaner assembly in paging Fmt Added new Scheduler test mode Added new test mode to CI Removed one of the prints Added doc comment, task test for i386 Removed test WIP Runtime tests work Have a global set in one task and reacted to in another. Also test that local variables are preserved after a task switch. Removed new lines Increased line length Move the allocation of the bool above the task creation
2020-07-18 22:46:24 +01:00
// TODO Will need to add the exit point
// Set up everything as a kernel task
2020-07-24 00:18:56 +01:00
stack.*[kernel_stack_bottom] = mem.virtToPhys(@ptrToInt(&paging.kernel_directory));
stack.*[kernel_stack_bottom + 1] = data_offset; // gs
stack.*[kernel_stack_bottom + 2] = data_offset; // fs
stack.*[kernel_stack_bottom + 3] = data_offset; // es
stack.*[kernel_stack_bottom + 4] = data_offset; // ds
stack.*[kernel_stack_bottom + 5] = 0; // edi
stack.*[kernel_stack_bottom + 6] = 0; // esi
Initial scheduler Fix TSS Also change to .{} syntax where appropriate. Added the SS segment Fixed spelling Refactoring GDT Multitasking working for now WIP scheduler Refactored Bitmap a bit WIP still Task switching working Handlers return the stack pointer that will be used to restore the tasks stack, normal handlers will return the same stack pointer it was called with where task switching will return the stack pointer of the next task and restore its state using the interrupt stub. Initial scheduler done Created a stage 2 init task Change u32 to usize Move Task to arch specific WIP WIP2 Removed esp from task, replaced with stack_pointer Removed the debug logs Fixed init task stack Change pickNextTask to pointer manipulation This allows less allocations so faster switching Temporary enable interrupts for some runtime tests PIT and RTC need interrupts enabled to run their runtime tests Renamed schedule => pickNextTask, comptime bitmap for pids not task init And some other stuff: No pub for the task anymore Use the leak detector allocator Fmt Fix unit tests And some other stuff :P PR review Moved Task out of arch and have the stack init in the arch file Mocking clean up Removed commented code Renamed createTask to scheduleTask where the user will have to provide a task to schedule Removed redundant pub in log runtime test Removed global allocator for scheduler Cleaner assembly in paging Fmt Added new Scheduler test mode Added new test mode to CI Removed one of the prints Added doc comment, task test for i386 Removed test WIP Runtime tests work Have a global set in one task and reacted to in another. Also test that local variables are preserved after a task switch. Removed new lines Increased line length Move the allocation of the bool above the task creation
2020-07-18 22:46:24 +01:00
// End of the stack
2020-07-24 00:18:56 +01:00
stack.*[kernel_stack_bottom + 7] = @ptrToInt(&stack.*[stack.len - 1]); // ebp
stack.*[kernel_stack_bottom + 8] = 0; // esp (temp) this won't be popped by popa bc intel is dump XD
stack.*[kernel_stack_bottom + 9] = 0; // ebx
stack.*[kernel_stack_bottom + 10] = 0; // edx
stack.*[kernel_stack_bottom + 11] = 0; // ecx
stack.*[kernel_stack_bottom + 12] = 0; // eax
stack.*[kernel_stack_bottom + 13] = 0; // int_num
stack.*[kernel_stack_bottom + 14] = 0; // error_code
stack.*[kernel_stack_bottom + 15] = entry_point; // eip
stack.*[kernel_stack_bottom + 16] = code_offset; // cs
stack.*[kernel_stack_bottom + 17] = 0x202; // eflags
if (!task.kernel) {
// Put the extra values on the kernel stack needed when chaning privilege levels
stack.*[kernel_stack_bottom + 18] = @ptrToInt(&task.user_stack[task.user_stack.len - 1]); // user_esp
stack.*[kernel_stack_bottom + 19] = data_offset; // user_ss
if (!builtin.is_test) {
// Create a new page directory for the user task by mirroring the kernel directory
// We need kernel mem mapped so we don't get a page fault when entering kernel code from an interrupt
task.vmm.payload = &(try allocator.allocAdvanced(paging.Directory, paging.PAGE_SIZE_4KB, 1, .exact))[0];
task.vmm.payload.* = paging.kernel_directory.copy();
stack.*[kernel_stack_bottom] = vmm.kernel_vmm.virtToPhys(@ptrToInt(task.vmm.payload)) catch |e| {
panic(@errorReturnTrace(), "Failed to get the physical address of the user task's page directory: {}\n", .{e});
};
}
}
task.stack_pointer = @ptrToInt(&stack.*[kernel_stack_bottom]);
Initial scheduler Fix TSS Also change to .{} syntax where appropriate. Added the SS segment Fixed spelling Refactoring GDT Multitasking working for now WIP scheduler Refactored Bitmap a bit WIP still Task switching working Handlers return the stack pointer that will be used to restore the tasks stack, normal handlers will return the same stack pointer it was called with where task switching will return the stack pointer of the next task and restore its state using the interrupt stub. Initial scheduler done Created a stage 2 init task Change u32 to usize Move Task to arch specific WIP WIP2 Removed esp from task, replaced with stack_pointer Removed the debug logs Fixed init task stack Change pickNextTask to pointer manipulation This allows less allocations so faster switching Temporary enable interrupts for some runtime tests PIT and RTC need interrupts enabled to run their runtime tests Renamed schedule => pickNextTask, comptime bitmap for pids not task init And some other stuff: No pub for the task anymore Use the leak detector allocator Fmt Fix unit tests And some other stuff :P PR review Moved Task out of arch and have the stack init in the arch file Mocking clean up Removed commented code Renamed createTask to scheduleTask where the user will have to provide a task to schedule Removed redundant pub in log runtime test Removed global allocator for scheduler Cleaner assembly in paging Fmt Added new Scheduler test mode Added new test mode to CI Removed one of the prints Added doc comment, task test for i386 Removed test WIP Runtime tests work Have a global set in one task and reacted to in another. Also test that local variables are preserved after a task switch. Removed new lines Increased line length Move the allocation of the bool above the task creation
2020-07-18 22:46:24 +01:00
}
pub fn getDevices(allocator: *Allocator) Allocator.Error![]Device {
return pci.getDevices(allocator);
}
2019-07-01 21:48:04 +01:00
///
/// Initialise the architecture
2019-07-01 21:48:04 +01:00
///
/// Arguments:
/// IN mem_profile: *const MemProfile - The memory profile of the computer. Used to set up
/// paging.
2019-07-01 21:48:04 +01:00
///
pub fn init(mem_profile: *const MemProfile) void {
gdt.init();
idt.init();
pic.init();
isr.init();
irq.init();
paging.init(mem_profile);
pit.init();
rtc.init();
2019-11-02 02:00:49 +00:00
syscalls.init();
2020-06-12 12:05:50 +01:00
// Initialise the VGA and TTY here since their tests belong the architecture and so should be a part of the
// arch init test messages
vga.init();
tty.init();
2019-07-01 21:48:04 +01:00
}
2019-09-17 18:24:27 +01:00
2020-07-24 00:18:56 +01:00
///
/// Check the state of the user task used for runtime testing for the expected values. These should mirror those in test/user_program.s
///
/// Arguments:
/// IN ctx: *const CpuState - The task's saved state
///
/// Return: bool
/// True if the expected values were found, else false
///
pub fn runtimeTestCheckUserTaskState(ctx: *const CpuState) bool {
return ctx.eax == 0xCAFE and ctx.ebx == 0xBEEF;
}
2019-09-17 18:24:27 +01:00
test "" {
2020-10-18 18:59:20 +01:00
std.testing.refAllDecls(@This());
2019-09-17 18:24:27 +01:00
}