A little IDT cleanup

This commit is contained in:
2024-04-01 12:29:26 +02:00
parent 6a9653d4ad
commit 7ca402d274
15 changed files with 735 additions and 654 deletions

View File

@@ -6,6 +6,48 @@
<fileSet type="globPattern" pattern="stl/*" />
</list>
</option>
<Objective-C-extensions>
<rules>
<rule entity="NAMESPACE" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
<rule entity="MACRO" visibility="ANY" specifier="ANY" prefix="" style="SCREAMING_SNAKE_CASE" suffix="" />
<rule entity="CLASS" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
<rule entity="STRUCT" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
<rule entity="ENUM" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
<rule entity="ENUMERATOR" visibility="ANY" specifier="ANY" prefix="" style="SCREAMING_SNAKE_CASE" suffix="" />
<rule entity="TYPEDEF" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="UNION" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="CLASS_MEMBER_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="STRUCT_MEMBER_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="GLOBAL_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="GLOBAL_VARIABLE" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="PARAMETER" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="LOCAL_VARIABLE" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="CLASS_MEMBER_FIELD,STRUCT_MEMBER_FIELD" visibility="PUBLIC" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="CLASS_MEMBER_FIELD,STRUCT_MEMBER_FIELD" visibility="PROTECTED,PRIVATE" specifier="ANY" prefix="_" style="SNAKE_CASE" suffix="" />
<rule entity="GLOBAL_VARIABLE" visibility="ANY" specifier="CONST" prefix="k" style="PASCAL_CASE" suffix="" />
</rules>
</Objective-C-extensions>
<Objective-C-extensions>
<rules>
<rule entity="NAMESPACE" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
<rule entity="MACRO" visibility="ANY" specifier="ANY" prefix="" style="SCREAMING_SNAKE_CASE" suffix="" />
<rule entity="CLASS" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
<rule entity="STRUCT" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
<rule entity="ENUM" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
<rule entity="ENUMERATOR" visibility="ANY" specifier="ANY" prefix="" style="SCREAMING_SNAKE_CASE" suffix="" />
<rule entity="TYPEDEF" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="UNION" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="CLASS_MEMBER_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="STRUCT_MEMBER_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="GLOBAL_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="GLOBAL_VARIABLE" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="PARAMETER" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="LOCAL_VARIABLE" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="CLASS_MEMBER_FIELD,STRUCT_MEMBER_FIELD" visibility="PUBLIC" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="CLASS_MEMBER_FIELD,STRUCT_MEMBER_FIELD" visibility="PROTECTED,PRIVATE" specifier="ANY" prefix="_" style="SNAKE_CASE" suffix="" />
<rule entity="GLOBAL_VARIABLE" visibility="ANY" specifier="CONST" prefix="k" style="PASCAL_CASE" suffix="" />
</rules>
</Objective-C-extensions>
<clangFormatSettings>
<option name="ENABLED" value="true" />
</clangFormatSettings>

File diff suppressed because it is too large Load Diff

View File

@@ -60,7 +60,7 @@ SerialTty::SerialTty() : Tty() {
task->start();
attach_interrupt(4, &SerialTty::isr, this);
IRQ_clear_mask(4);
Arch::IDT::IRQ_clear_mask(4);
}
void SerialTty::isr(void *tty) {
((SerialTty *) tty)->this_isr();

View File

@@ -40,7 +40,7 @@ extern "C" __attribute__((unused)) void _start(void) {
barrier();
Arch::GDT::gdt_setup();
barrier();
idt_init();
Arch::IDT::idt_init();
barrier();
init_serial();
barrier();

View File

@@ -22,7 +22,7 @@ namespace Arch::GDT {
unsigned int base_high : 8;
//
uint64_t selector() volatile;
[[nodiscard]] uint64_t selector() const volatile;
} __attribute__((packed));
struct gdt_tss_entry_bits {
@@ -81,7 +81,7 @@ namespace Arch::GDT {
} __attribute__((packed)) gdtr;
}
inline uint64_t gdt_entry_bits::selector() volatile {
inline uint64_t gdt_entry_bits::selector() const volatile {
return (((uint64_t) this) - ((uint64_t) &gdt_null));
}

View File

@@ -5,17 +5,15 @@
#ifndef OS1_GLOBALS_H
#define OS1_GLOBALS_H
#include <stdint.h>
#include <cstdint>
#define KERN_STACK_SIZE (1024 * 1024)
extern uint64_t KERN_stack[KERN_STACK_SIZE] __attribute__((aligned(16)));
class AddressSpace;
extern AddressSpace *BOOT_AddressSpace;
extern AddressSpace *KERN_AddressSpace;
#define TASK_POINTER 0x10000
#endif //OS1_GLOBALS_H

View File

@@ -5,7 +5,18 @@
#include "task.hpp"
extern "C" __attribute__((noreturn)) void exception_handler(void) {
extern "C" __attribute__((noreturn)) void exception_handler_err(uint64_t code) {
//FIXME:
if (Scheduler::cur_task()->_mode == Task::TaskMode::TASKMODE_USER) {
writestr_no_yield("Task ded");
Scheduler::cur_task()->_state = Task::TaskState::TS_BLOCKED;
_yield_self_kern();
} else {
writestr_no_yield("Kernel ded");
_hcf();
}
}
extern "C" __attribute__((noreturn)) void exception_handler_no_err(void) {
//FIXME:
if (Scheduler::cur_task()->_mode == Task::TaskMode::TASKMODE_USER) {
writestr_no_yield("Task ded");

View File

@@ -2,21 +2,22 @@
%include "task.inc.asm"
extern exception_handler_err
extern exception_handler_no_err
section .text
%macro isr_err_stub 1
isr_stub_%+%1:
pop rdi ; Keep the stacktrace
call exception_handler
call exception_handler_err
iretq
%endmacro
%macro isr_no_err_stub 1
isr_stub_%+%1:
call exception_handler
call exception_handler_no_err
iretq
%endmacro
extern exception_handler
isr_no_err_stub 0
isr_no_err_stub 1
isr_no_err_stub 2

View File

@@ -5,10 +5,15 @@
#include "io.hpp"
#include "misc.hpp"
#include "task.hpp"
#include "task_arch.hpp"
#include "timer.hpp"
__attribute__((aligned(0x10))) static idt_entry_t idt[256]; // Create an array of IDT entries; aligned for performance
static idtr_t idtr;
namespace Arch::IDT {
__attribute__((aligned(0x10))) static IdtEntry idt[256]; // Create an array of IDT entries; aligned for performance
//
static Idtr idtr;
extern "C" void pic1_irq_0();
extern "C" void pic1_irq_1();
@@ -30,7 +35,7 @@ extern "C" void pic2_irq_7();
void idt_set_descriptor(uint8_t vector, void (*isr)(), uint8_t flags) {
idt_entry_t *descriptor = &idt[vector];
IdtEntry *descriptor = &idt[vector];
descriptor->isr_low = (uint64_t) isr & 0xFFFF;
descriptor->kernel_cs = Arch::GDT::gdt_code.selector();
@@ -49,23 +54,23 @@ void idt_init() {
idt_set_descriptor(vector, isr_stub_table[vector], 0x8E);
}
idt_set_descriptor(PIC1_OFFSET + 0, pic1_irq_0, 0x8e);
idt_set_descriptor(PIC1_OFFSET + 1, pic1_irq_1, 0x8e);
idt_set_descriptor(PIC1_OFFSET + 2, pic1_irq_2, 0x8e);
idt_set_descriptor(PIC1_OFFSET + 3, pic1_irq_3, 0x8e);
idt_set_descriptor(PIC1_OFFSET + 4, pic1_irq_4, 0x8e);
idt_set_descriptor(PIC1_OFFSET + 5, pic1_irq_5, 0x8e);
idt_set_descriptor(PIC1_OFFSET + 6, pic1_irq_6, 0x8e);
idt_set_descriptor(PIC1_OFFSET + 7, pic1_irq_7, 0x8e);
idt_set_descriptor(kPIC1_OFFSET + 0, pic1_irq_0, 0x8e);
idt_set_descriptor(kPIC1_OFFSET + 1, pic1_irq_1, 0x8e);
idt_set_descriptor(kPIC1_OFFSET + 2, pic1_irq_2, 0x8e);
idt_set_descriptor(kPIC1_OFFSET + 3, pic1_irq_3, 0x8e);
idt_set_descriptor(kPIC1_OFFSET + 4, pic1_irq_4, 0x8e);
idt_set_descriptor(kPIC1_OFFSET + 5, pic1_irq_5, 0x8e);
idt_set_descriptor(kPIC1_OFFSET + 6, pic1_irq_6, 0x8e);
idt_set_descriptor(kPIC1_OFFSET + 7, pic1_irq_7, 0x8e);
idt_set_descriptor(PIC2_OFFSET + 0, pic2_irq_0, 0x8e);
idt_set_descriptor(PIC2_OFFSET + 1, pic2_irq_1, 0x8e);
idt_set_descriptor(PIC2_OFFSET + 2, pic2_irq_2, 0x8e);
idt_set_descriptor(PIC2_OFFSET + 3, pic2_irq_3, 0x8e);
idt_set_descriptor(PIC2_OFFSET + 4, pic2_irq_4, 0x8e);
idt_set_descriptor(PIC2_OFFSET + 5, pic2_irq_5, 0x8e);
idt_set_descriptor(PIC2_OFFSET + 6, pic2_irq_6, 0x8e);
idt_set_descriptor(PIC2_OFFSET + 7, pic2_irq_7, 0x8e);
idt_set_descriptor(kPIC2_OFFSET + 0, pic2_irq_0, 0x8e);
idt_set_descriptor(kPIC2_OFFSET + 1, pic2_irq_1, 0x8e);
idt_set_descriptor(kPIC2_OFFSET + 2, pic2_irq_2, 0x8e);
idt_set_descriptor(kPIC2_OFFSET + 3, pic2_irq_3, 0x8e);
idt_set_descriptor(kPIC2_OFFSET + 4, pic2_irq_4, 0x8e);
idt_set_descriptor(kPIC2_OFFSET + 5, pic2_irq_5, 0x8e);
idt_set_descriptor(kPIC2_OFFSET + 6, pic2_irq_6, 0x8e);
idt_set_descriptor(kPIC2_OFFSET + 7, pic2_irq_7, 0x8e);
barrier();
__asm__ volatile("lidt %0"
@@ -79,46 +84,46 @@ void idt_init() {
void PIC_sendEOI(unsigned char irq) {
if (irq >= 8)
outb(PIC2_COMMAND, PIC_EOI);
outb(kPIC2_COMMAND, kPIC_EOI);
outb(PIC1_COMMAND, PIC_EOI);
outb(kPIC1_COMMAND, kPIC_EOI);
}
void PIC_init() {
unsigned char a1, a2;
a1 = inb(PIC1_DATA); // save masks
a2 = inb(PIC2_DATA);
a1 = inb(kPIC1_DATA); // save masks
a2 = inb(kPIC2_DATA);
outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); // starts the initialization sequence (in cascade mode)
outb(kPIC1_COMMAND, kICW1_INIT | kICW1_ICW4); // starts the initialization sequence (in cascade mode)
io_wait();
outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4);
outb(kPIC2_COMMAND, kICW1_INIT | kICW1_ICW4);
io_wait();
outb(PIC1_DATA, PIC1_OFFSET); // ICW2: Master PIC vector offset
outb(kPIC1_DATA, kPIC1_OFFSET); // ICW2: Master PIC vector offset
io_wait();
outb(PIC2_DATA, PIC2_OFFSET); // ICW2: Slave PIC vector offset
outb(kPIC2_DATA, kPIC2_OFFSET); // ICW2: Slave PIC vector offset
io_wait();
outb(PIC1_DATA, 4); // ICW3: tell Master PIC that there is a slave PIC at IRQ2 (0000 0100)
outb(kPIC1_DATA, 4); // ICW3: tell Master PIC that there is a slave PIC at IRQ2 (0000 0100)
io_wait();
outb(PIC2_DATA, 2); // ICW3: tell Slave PIC its cascade identity (0000 0010)
outb(kPIC2_DATA, 2); // ICW3: tell Slave PIC its cascade identity (0000 0010)
io_wait();
outb(PIC1_DATA, ICW4_8086); // ICW4: have the PICs use 8086 mode (and not 8080 mode)
outb(kPIC1_DATA, kICW4_8086); // ICW4: have the PICs use 8086 mode (and not 8080 mode)
io_wait();
outb(PIC2_DATA, ICW4_8086);
outb(kPIC2_DATA, kICW4_8086);
io_wait();
outb(PIC1_DATA, a1); // restore saved masks.
outb(PIC2_DATA, a2);
outb(kPIC1_DATA, a1); // restore saved masks.
outb(kPIC2_DATA, a2);
}
void IRQ_set_mask(unsigned char IRQline) {
uint16_t port;
uint8_t value;
if (IRQline < 8) {
port = PIC1_DATA;
port = kPIC1_DATA;
} else {
port = PIC2_DATA;
port = kPIC2_DATA;
IRQline -= 8;
}
value = inb(port) | (1 << IRQline);
@@ -130,9 +135,9 @@ void IRQ_clear_mask(unsigned char IRQline) {
uint8_t value;
if (IRQline < 8) {
port = PIC1_DATA;
port = kPIC1_DATA;
} else {
port = PIC2_DATA;
port = kPIC2_DATA;
IRQline -= 8;
}
value = inb(port) & ~(1 << IRQline);
@@ -144,25 +149,26 @@ void IRQ_clear_mask(unsigned char IRQline) {
static uint16_t __pic_get_irq_reg(int ocw3) {
/* OCW3 to PIC CMD to get the register values. PIC2 is chained, and
* represents IRQs 8-15. PIC1 is IRQs 0-7, with 2 being the chain */
outb(PIC1_COMMAND, ocw3);
outb(PIC2_COMMAND, ocw3);
return (inb(PIC2_COMMAND) << 8) | inb(PIC1_COMMAND);
outb(kPIC1_COMMAND, ocw3);
outb(kPIC2_COMMAND, ocw3);
return (inb(kPIC2_COMMAND) << 8) | inb(kPIC1_COMMAND);
}
/* Returns the combined value of the cascaded PICs irq request register */
uint16_t pic_get_irr(void) {
return __pic_get_irq_reg(PIC_READ_IRR);
return __pic_get_irq_reg(kPIC_READ_IRR);
}
/* Returns the combined value of the cascaded PICs in-service register */
uint16_t pic_get_isr(void) {
return __pic_get_irq_reg(PIC_READ_ISR);
return __pic_get_irq_reg(kPIC_READ_ISR);
}
static int_handler_t handlers[256];
static void *handlers_args[256];
extern "C" void pic1_irq_real_0(TaskFrame *frame) {
// TODO: guarantee alignment in the asm part
extern "C" __attribute__((force_align_arg_pointer)) void pic1_irq_real_0(TaskFrame *frame) {
timer_tick();
Scheduler::switch_task(frame);
PIC_sendEOI(0);
@@ -177,7 +183,7 @@ extern "C" void pic1_irq_real_2() {
extern "C" void pic1_irq_real_3() {
PIC_sendEOI(3);
}
extern "C" void pic1_irq_real_4() {
extern "C" __attribute__((force_align_arg_pointer)) void pic1_irq_real_4() {
if (handlers[4] != nullptr) {
handlers[4](handlers_args[4]);
}
@@ -220,14 +226,16 @@ extern "C" void pic2_irq_real_7() {
// Probaby wrong
int irr = pic_get_irr();
if (!(irr & (0x80 << 8))) {
outb(PIC1_COMMAND, PIC_EOI);
outb(kPIC1_COMMAND, kPIC_EOI);
return;
}
PIC_sendEOI(15);
}
} // namespace Arch::IDT
void attach_interrupt(unsigned num, int_handler_t handler, void *firstarg) {
handlers[num] = handler;
handlers_args[num] = firstarg;
Arch::IDT::handlers[num] = handler;
Arch::IDT::handlers_args[num] = firstarg;
}

View File

@@ -1,34 +1,35 @@
#ifndef OS1_IDT_H
#define OS1_IDT_H
#include <stddef.h>
#include <stdint.h>
#include <cstddef>
#include <cstdint>
#define PIC1 0x20 /* IO base address for master PIC */
#define PIC2 0xA0 /* IO base address for slave PIC */
#define PIC1_COMMAND PIC1
#define PIC1_DATA (PIC1 + 1)
#define PIC2_COMMAND PIC2
#define PIC2_DATA (PIC2 + 1)
#define PIC_EOI 0x20 /* End-of-interrupt command code */
namespace Arch::IDT {
static constexpr int kPIC1 = 0x20; /* IO base address for master PIC */
static constexpr int kPIC2 = 0xA0; /* IO base address for slave PIC */
static constexpr int kPIC1_COMMAND = kPIC1;
static constexpr int kPIC1_DATA = (kPIC1 + 1);
static constexpr int kPIC2_COMMAND = kPIC2;
static constexpr int kPIC2_DATA = (kPIC2 + 1);
static constexpr int kPIC_EOI = 0x20; /* End-of-interrupt command code */
#define ICW1_ICW4 0x01 /* Indicates that ICW4 will be present */
#define ICW1_SINGLE 0x02 /* Single (cascade) mode */
#define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */
#define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */
#define ICW1_INIT 0x10 /* Initialization - required! */
static constexpr int kICW1_ICW4 = 0x01; /* Indicates that ICW4 will be present */
static constexpr int kICW1_SINGLE = 0x02; /* Single (cascade) mode */
static constexpr int kICW1_INTERVAL4 = 0x04; /* Call address interval 4 (8) */
static constexpr int kICW1_LEVEL = 0x08; /* Level triggered (edge) mode */
static constexpr int kICW1_INIT = 0x10; /* Initialization - required! */
#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */
#define ICW4_AUTO 0x02 /* Auto (normal) EOI */
#define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */
#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */
#define ICW4_SFNM 0x10 /* Special fully nested (not) */
static constexpr int kICW4_8086 = 0x01; /* 8086/88 (MCS-80/85) mode */
static constexpr int kICW4_AUTO = 0x02; /* Auto (normal) EOI */
static constexpr int kICW4_BUF_SLAVE = 0x08; /* Buffered mode/slave */
static constexpr int kICW4_BUF_MASTER = 0x0C; /* Buffered mode/master */
static constexpr int kICW4_SFNM = 0x10; /* Special fully nested (not) */
#define PIC_READ_IRR 0x0a /* OCW3 irq ready next CMD read */
#define PIC_READ_ISR 0x0b /* OCW3 irq service next CMD read */
static constexpr int kPIC_READ_IRR = 0x0a; /* OCW3 irq ready next CMD read */
static constexpr int kPIC_READ_ISR = 0x0b; /* OCW3 irq service next CMD read */
#define PIC1_OFFSET 0x20
#define PIC2_OFFSET 0x28
static constexpr int kPIC1_OFFSET = 0x20;
static constexpr int kPIC2_OFFSET = 0x28;
void PIC_sendEOI(unsigned char irq);
void PIC_init();
@@ -37,7 +38,7 @@ void IRQ_clear_mask(unsigned char IRQline);
uint16_t pic_get_irr(void);
uint16_t pic_get_isr(void);
typedef struct {
struct IdtEntry {
uint16_t isr_low; // The lower 16 bits of the ISR's address
uint16_t kernel_cs; // The GDT segment selector that the CPU will load into CS before calling the ISR
uint8_t ist; // The IST in the TSS that the CPU will load into RSP; set to zero for now
@@ -45,52 +46,23 @@ typedef struct {
uint16_t isr_mid; // The higher 16 bits of the lower 32 bits of the ISR's address
uint32_t isr_high; // The higher 32 bits of the ISR's address
uint32_t reserved; // Set to zero
} __attribute__((packed)) idt_entry_t;
} __attribute__((packed));
typedef struct {
struct Idtr {
uint16_t limit;
uint64_t base;
} __attribute__((packed)) idtr_t;
} __attribute__((packed));
#define IDT_GUARD 0xdeadbe3fdeadb3efULL
// Assuming the compiler understands that this is pushed on the stack in the correct order
struct TaskFrame {
uint64_t guard;
uint64_t guard2; // To keep stack aligned after pushaq
uint64_t r15;
uint64_t r14;
uint64_t r13;
uint64_t r12;
uint64_t r11;
uint64_t r10;
uint64_t r9;
uint64_t r8;
uint64_t rdi;
uint64_t rsi;
uint64_t rbp;
uint64_t rbx;
uint64_t rdx;
uint64_t rcx;
uint64_t rax;
uint64_t ip;
uint64_t cs;
uint64_t flags;
uint64_t sp;
uint64_t ss;
}
__attribute__((packed));
extern "C" void exception_handler(void);
extern "C" void exception_handler_err(uint64_t code);
extern "C" void exception_handler_no_err(void);
void idt_set_descriptor(uint8_t vector, void (*isr)(), uint8_t flags);
void idt_init(void);
void idt_init();
extern void (*isr_stub_table[])();
extern "C" void (*isr_stub_table[])();
} // namespace Arch::IDT
using int_handler_t = void (*)(void *);

View File

@@ -18,7 +18,8 @@ struct FourPages {
enum PageStatus second : 2;
enum PageStatus third : 2;
enum PageStatus fourth : 2;
};
} __attribute__((packed));
static_assert(sizeof(FourPages) == 1);
void parse_limine_memmap(struct limine_memmap_entry *entries, unsigned int num, uint64_t what_is_considered_free);

View File

@@ -24,12 +24,12 @@
char temp_fxsave[512] __attribute__((aligned(16)));
void sanity_check_frame(TaskFrame *cur_frame) {
void sanity_check_frame(Arch::TaskFrame *cur_frame) {
// TODO: This makes sense to check when entering, but not when switching
// assert((((uintptr_t) cur_frame) & 0xFULL) == 0);
assert2((void *) cur_frame->ip != NULL, "Sanity check");
assert2((void *) cur_frame->sp != NULL, "Sanity check");
assert2(cur_frame->guard == IDT_GUARD, "IDT Guard wrong!");
assert2(cur_frame->guard == Arch::kIDT_GUARD, "IDT Guard wrong!");
assert(cur_frame->ss != 0);
assert(cur_frame->cs != 0);
assert(cur_frame->sp != 0);
@@ -111,7 +111,7 @@ Task::Task(Task::TaskMode mode, void (*entrypoint)(), const char *name) {
for (int i = 0; i < 512; i++) _fxsave->_fxsave[i] = 0;
_frame.flags = flags();
_frame.guard = IDT_GUARD;
_frame.guard = Arch::kIDT_GUARD;
if (mode == TaskMode::TASKMODE_USER) {
_ownAddressSpace = UniquePtr(new AddressSpace());
_vma = UniquePtr<VMA>(new VMA(_ownAddressSpace.get()));
@@ -276,7 +276,7 @@ void Scheduler::init_tasks() {
atomic_store(&initialized, true);
}
extern "C" void Scheduler::switch_task(TaskFrame *cur_frame) {
extern "C" void Scheduler::switch_task(Arch::TaskFrame *cur_frame) {
assert2(!are_interrupts_enabled(), "Switching tasks with enabled interrupts!");
if (!atomic_load(&initialized)) return;
sanity_check_frame(cur_frame);

View File

@@ -10,6 +10,7 @@
#include "SkipList.hpp"
#include "String.hpp"
#include "idt.hpp"
#include "task_arch.hpp"
#define TASK_SS 16384
@@ -58,7 +59,7 @@ public:
} __attribute__((aligned(16)));
uint64_t _entry_ksp_val;
TaskFrame _frame;
Arch::TaskFrame _frame;
TaskPID _pid;
std::atomic<uint64_t> _used_time;
@@ -102,7 +103,7 @@ namespace Scheduler {
void unblock(List<Task *>::Node *what);
void unblock_nolock(List<Task *>::Node *what);
extern "C" void switch_task(TaskFrame *cur_frame);
extern "C" void switch_task(Arch::TaskFrame *cur_frame);
// TODO: that's quite inefficient!
SkipList<uint64_t, std::pair<String, Task::TaskPID>> getTaskTimePerPid();

View File

@@ -0,0 +1,44 @@
//
// Created by Stepan Usatiuk on 01.04.2024.
//
#ifndef FICUS_TASK_ARCH_HPP
#define FICUS_TASK_ARCH_HPP
#include <cstdint>
namespace Arch {
static constexpr uint64_t kIDT_GUARD = 0xdeadbe3fdeadb3efULL;
// Assuming the compiler understands that this is pushed on the stack in the correct order
struct TaskFrame {
uint64_t guard;
uint64_t guard2; // To keep stack aligned after pushaq
uint64_t r15;
uint64_t r14;
uint64_t r13;
uint64_t r12;
uint64_t r11;
uint64_t r10;
uint64_t r9;
uint64_t r8;
uint64_t rdi;
uint64_t rsi;
uint64_t rbp;
uint64_t rbx;
uint64_t rdx;
uint64_t rcx;
uint64_t rax;
uint64_t ip;
uint64_t cs;
uint64_t flags;
uint64_t sp;
uint64_t ss;
} __attribute__((packed));
} // namespace Arch
#endif //FICUS_TASK_ARCH_HPP

View File

@@ -46,7 +46,7 @@ static_assert(MICROS_PER_TICK >= 1);
void init_timer() {
outb(0x43, 0b00110100);
set_pit_count(RELOAD_VAL);
IRQ_clear_mask(0);
Arch::IDT::IRQ_clear_mask(0);
}
void timer_tick() {