diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index 10fee6cfe..de855dd11 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -6,6 +6,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ficus-toolchain/newlib/newlib-4.4.0.20231231/.idea/workspace.xml b/ficus-toolchain/newlib/newlib-4.4.0.20231231/.idea/workspace.xml
index d40034a20..9657981e2 100644
--- a/ficus-toolchain/newlib/newlib-4.4.0.20231231/.idea/workspace.xml
+++ b/ficus-toolchain/newlib/newlib-4.4.0.20231231/.idea/workspace.xml
@@ -4144,7 +4144,7 @@
-
+
@@ -4163,7 +4163,7 @@
-
+
-
+ {
+ "associatedIndex": 4
+}
- {
+ "keyToString": {
+ "RunOnceActivity.OpenProjectViewOnStart": "true",
+ "RunOnceActivity.ShowReadmeOnStart": "true",
+ "RunOnceActivity.cidr.known.project.marker": "true",
+ "RunOnceActivity.readMode.enableVisualFormatting": "true",
+ "cf.advertisement.text.has.clang-format": "true",
+ "cf.first.check.clang-format": "false",
+ "cidr.known.project.marker": "true",
+ "git-widget-placeholder": "main",
+ "last_opened_file_path": "/Users/stepus53/projects/ficus/ficus-toolchain/newlib/newlib-4.4.0.20231231",
+ "node.js.detected.package.eslint": "true",
+ "node.js.detected.package.tslint": "true",
+ "node.js.selected.package.eslint": "(autodetect)",
+ "node.js.selected.package.tslint": "(autodetect)",
+ "nodejs_package_manager_path": "npm",
+ "settings.editor.selected.configurable": "MakefileSettings",
+ "vue.rearranger.settings.migration": "true"
}
-}]]>
+}
-
-
-
-
-
@@ -24879,11 +24875,84 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
@@ -24891,6 +24960,7 @@
+
@@ -24918,8 +24988,8 @@
-
+
@@ -24930,7 +25000,6 @@
-
@@ -24945,8 +25014,8 @@
-
+
@@ -24959,7 +25028,7 @@
-
+
@@ -24974,8 +25043,8 @@
-
+
@@ -24988,7 +25057,7 @@
-
+
@@ -25003,8 +25072,8 @@
-
+
@@ -25017,7 +25086,7 @@
-
+
@@ -25032,8 +25101,8 @@
-
+
@@ -25046,7 +25115,7 @@
-
+
@@ -25061,8 +25130,8 @@
-
+
@@ -25075,7 +25144,7 @@
-
+
@@ -25090,8 +25159,8 @@
-
+
@@ -25104,7 +25173,7 @@
-
+
@@ -25119,8 +25188,8 @@
-
+
@@ -25133,7 +25202,7 @@
-
+
@@ -25148,8 +25217,8 @@
-
+
@@ -25162,8 +25231,9 @@
-
+
+
@@ -25189,12 +25259,13 @@
+
-
+
@@ -25225,8 +25296,8 @@
-
+
@@ -25237,7 +25308,14 @@
-
+
+
+
+
+
+
+
+
@@ -25264,11 +25342,13 @@
+
+
@@ -25300,8 +25380,8 @@
-
+
@@ -25312,7 +25392,6 @@
-
@@ -25327,8 +25406,8 @@
-
+
@@ -25341,7 +25420,7 @@
-
+
@@ -25356,8 +25435,8 @@
-
+
@@ -25370,7 +25449,7 @@
-
+
@@ -25385,8 +25464,8 @@
-
+
@@ -25399,7 +25478,7 @@
-
+
@@ -25414,8 +25493,8 @@
-
+
@@ -25428,7 +25507,7 @@
-
+
@@ -25443,8 +25522,8 @@
-
+
@@ -25457,7 +25536,7 @@
-
+
@@ -25472,8 +25551,8 @@
-
+
@@ -25486,7 +25565,7 @@
-
+
@@ -25501,8 +25580,8 @@
-
+
@@ -25515,7 +25594,7 @@
-
+
@@ -25530,8 +25609,8 @@
-
+
@@ -25544,7 +25623,7 @@
-
+
@@ -25571,6 +25650,7 @@
+
@@ -25613,8 +25693,8 @@
-
+
@@ -25639,8 +25719,8 @@
-
+
@@ -25667,8 +25747,8 @@
-
+
@@ -25695,8 +25775,8 @@
-
+
@@ -25723,8 +25803,8 @@
-
+
@@ -25751,8 +25831,8 @@
-
+
@@ -25779,8 +25859,8 @@
-
+
@@ -25807,8 +25887,8 @@
-
+
@@ -25835,8 +25915,8 @@
-
+
@@ -25849,8 +25929,8 @@
-
+
@@ -25876,12 +25956,13 @@
+
-
+
@@ -25912,8 +25993,8 @@
-
+
@@ -25924,7 +26005,6 @@
-
@@ -25951,11 +26031,14 @@
+
+
+
@@ -25969,8 +26052,6 @@
-
-
@@ -26001,8 +26082,8 @@
-
+
@@ -26013,7 +26094,14 @@
-
+
+
+
+
+
+
+
+
@@ -26040,12 +26128,15 @@
+
-
+
+
+
@@ -26076,8 +26167,8 @@
-
+
@@ -26088,7 +26179,14 @@
-
+
+
+
+
+
+
+
+
@@ -26115,12 +26213,13 @@
+
-
+
@@ -26151,8 +26250,8 @@
-
+
@@ -26163,7 +26262,14 @@
-
+
+
+
+
+
+
+
+
@@ -26190,12 +26296,13 @@
+
-
+
@@ -26215,9 +26322,8 @@
-
-
+
@@ -26248,8 +26354,8 @@
-
+
@@ -26260,7 +26366,6 @@
-
@@ -26287,12 +26392,13 @@
+
-
+
@@ -26323,8 +26429,8 @@
-
+
@@ -26335,7 +26441,6 @@
-
@@ -26362,11 +26467,13 @@
+
+
@@ -26377,8 +26484,8 @@
-
+
@@ -26387,7 +26494,6 @@
-
@@ -26418,8 +26524,8 @@
-
+
@@ -26430,7 +26536,6 @@
-
@@ -26457,15 +26562,16 @@
+
+
-
@@ -26496,8 +26602,8 @@
-
+
@@ -26508,7 +26614,6 @@
-
@@ -26535,12 +26640,13 @@
+
-
+
@@ -26567,12 +26673,13 @@
+
-
+
@@ -26603,8 +26710,8 @@
-
+
@@ -26615,7 +26722,6 @@
-
@@ -26642,16 +26748,17 @@
+
+
-
@@ -26682,8 +26789,8 @@
-
+
@@ -26694,7 +26801,6 @@
-
@@ -26721,11 +26827,85 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -26762,8 +26942,8 @@
-
+
@@ -26788,8 +26968,8 @@
-
+
@@ -26816,8 +26996,8 @@
-
+
@@ -26844,8 +27024,8 @@
-
+
@@ -26872,8 +27052,8 @@
-
+
@@ -26900,8 +27080,8 @@
-
+
@@ -26928,8 +27108,8 @@
-
+
@@ -26956,8 +27136,8 @@
-
+
@@ -26984,8 +27164,8 @@
-
+
@@ -27058,8 +27238,8 @@
-
+
@@ -27130,8 +27310,8 @@
-
+
@@ -27156,8 +27336,8 @@
-
+
@@ -27184,8 +27364,8 @@
-
+
@@ -27212,8 +27392,8 @@
-
+
@@ -27240,8 +27420,8 @@
-
+
@@ -27268,8 +27448,8 @@
-
+
@@ -27296,8 +27476,8 @@
-
+
@@ -27324,8 +27504,8 @@
-
+
@@ -27352,8 +27532,8 @@
-
+
@@ -27433,8 +27613,8 @@
-
+
@@ -27459,8 +27639,8 @@
-
+
@@ -27487,8 +27667,8 @@
-
+
@@ -27515,8 +27695,8 @@
-
+
@@ -27543,8 +27723,8 @@
-
+
@@ -27571,8 +27751,8 @@
-
+
@@ -27599,8 +27779,8 @@
-
+
@@ -27627,8 +27807,8 @@
-
+
@@ -27655,8 +27835,8 @@
-
+
@@ -27729,8 +27909,8 @@
-
+
@@ -27801,8 +27981,8 @@
-
+
@@ -27873,8 +28053,8 @@
-
+
@@ -27945,8 +28125,8 @@
-
+
@@ -28036,8 +28216,8 @@
-
+
@@ -28108,8 +28288,8 @@
-
+
@@ -28161,8 +28341,8 @@
-
+
@@ -28199,8 +28379,8 @@
-
+
@@ -28274,8 +28454,8 @@
-
+
@@ -28377,8 +28557,8 @@
-
+
@@ -28449,8 +28629,8 @@
-
+
@@ -28521,8 +28701,8 @@
-
+
@@ -28593,8 +28773,8 @@
-
+
@@ -28636,79 +28816,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -28739,8 +28847,8 @@
-
+
@@ -28751,7 +28859,6 @@
-
@@ -28778,12 +28885,13 @@
+
-
+
@@ -28814,8 +28922,8 @@
-
+
@@ -28826,7 +28934,14 @@
-
+
+
+
+
+
+
+
+
@@ -28853,13 +28968,14 @@
+
+
-
@@ -28872,6 +28988,7 @@
+
@@ -28884,131 +29001,10 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -29020,6 +29016,13 @@
1711795167187
+
+
+
+
+
+
+
diff --git a/src/arch/x86/SerialTty.cpp b/src/arch/x86/SerialTty.cpp
index dd60b9a65..93f3e82c3 100644
--- a/src/arch/x86/SerialTty.cpp
+++ b/src/arch/x86/SerialTty.cpp
@@ -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();
diff --git a/src/arch/x86/boot.cpp b/src/arch/x86/boot.cpp
index e93bac25b..03d2e44ec 100644
--- a/src/arch/x86/boot.cpp
+++ b/src/arch/x86/boot.cpp
@@ -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();
diff --git a/src/arch/x86/gdt.hpp b/src/arch/x86/gdt.hpp
index 98b845ced..9a959d637 100644
--- a/src/arch/x86/gdt.hpp
+++ b/src/arch/x86/gdt.hpp
@@ -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));
}
diff --git a/src/arch/x86/globals.hpp b/src/arch/x86/globals.hpp
index bd03f0485..d3c4b3d91 100644
--- a/src/arch/x86/globals.hpp
+++ b/src/arch/x86/globals.hpp
@@ -5,17 +5,15 @@
#ifndef OS1_GLOBALS_H
#define OS1_GLOBALS_H
-#include
+#include
#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
diff --git a/src/arch/x86/handle_exception.cpp b/src/arch/x86/handle_exception.cpp
index 8b574507a..6620fdd4e 100644
--- a/src/arch/x86/handle_exception.cpp
+++ b/src/arch/x86/handle_exception.cpp
@@ -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");
diff --git a/src/arch/x86/idt.asm b/src/arch/x86/idt.asm
index 5079b3ecb..e8defaa3d 100644
--- a/src/arch/x86/idt.asm
+++ b/src/arch/x86/idt.asm
@@ -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
diff --git a/src/arch/x86/idt.cpp b/src/arch/x86/idt.cpp
index a4207c56f..0b049ca63 100644
--- a/src/arch/x86/idt.cpp
+++ b/src/arch/x86/idt.cpp
@@ -5,229 +5,237 @@
#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 {
-extern "C" void pic1_irq_0();
-extern "C" void pic1_irq_1();
-extern "C" void pic1_irq_2();
-extern "C" void pic1_irq_3();
-extern "C" void pic1_irq_4();
-extern "C" void pic1_irq_5();
-extern "C" void pic1_irq_6();
-extern "C" void pic1_irq_7();
+ __attribute__((aligned(0x10))) static IdtEntry idt[256]; // Create an array of IDT entries; aligned for performance
-extern "C" void pic2_irq_0();
-extern "C" void pic2_irq_1();
-extern "C" void pic2_irq_2();
-extern "C" void pic2_irq_3();
-extern "C" void pic2_irq_4();
-extern "C" void pic2_irq_5();
-extern "C" void pic2_irq_6();
-extern "C" void pic2_irq_7();
+ //
+ static Idtr idtr;
+
+ extern "C" void pic1_irq_0();
+ extern "C" void pic1_irq_1();
+ extern "C" void pic1_irq_2();
+ extern "C" void pic1_irq_3();
+ extern "C" void pic1_irq_4();
+ extern "C" void pic1_irq_5();
+ extern "C" void pic1_irq_6();
+ extern "C" void pic1_irq_7();
+
+ extern "C" void pic2_irq_0();
+ extern "C" void pic2_irq_1();
+ extern "C" void pic2_irq_2();
+ extern "C" void pic2_irq_3();
+ extern "C" void pic2_irq_4();
+ extern "C" void pic2_irq_5();
+ extern "C" void pic2_irq_6();
+ extern "C" void pic2_irq_7();
-void idt_set_descriptor(uint8_t vector, void (*isr)(), uint8_t flags) {
- idt_entry_t *descriptor = &idt[vector];
+ void idt_set_descriptor(uint8_t vector, void (*isr)(), uint8_t flags) {
+ IdtEntry *descriptor = &idt[vector];
- descriptor->isr_low = (uint64_t) isr & 0xFFFF;
- descriptor->kernel_cs = Arch::GDT::gdt_code.selector();
- descriptor->ist = 0;
- descriptor->attributes = flags;
- descriptor->isr_mid = ((uint64_t) isr >> 16) & 0xFFFF;
- descriptor->isr_high = ((uint64_t) isr >> 32) & 0xFFFFFFFF;
- descriptor->reserved = 0;
-}
-
-void idt_init() {
- idtr.base = (uintptr_t) &idt[0];
- idtr.limit = (uint16_t) ((uint64_t) &idt[255] - (uint64_t) &idt[0]);
-
- for (uint8_t vector = 0; vector < 32; vector++) {
- idt_set_descriptor(vector, isr_stub_table[vector], 0x8E);
+ descriptor->isr_low = (uint64_t) isr & 0xFFFF;
+ descriptor->kernel_cs = Arch::GDT::gdt_code.selector();
+ descriptor->ist = 0;
+ descriptor->attributes = flags;
+ descriptor->isr_mid = ((uint64_t) isr >> 16) & 0xFFFF;
+ descriptor->isr_high = ((uint64_t) isr >> 32) & 0xFFFFFFFF;
+ descriptor->reserved = 0;
}
- 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);
+ void idt_init() {
+ idtr.base = (uintptr_t) &idt[0];
+ idtr.limit = (uint16_t) ((uint64_t) &idt[255] - (uint64_t) &idt[0]);
- 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);
+ for (uint8_t vector = 0; vector < 32; vector++) {
+ idt_set_descriptor(vector, isr_stub_table[vector], 0x8E);
+ }
- barrier();
- __asm__ volatile("lidt %0"
- :
- : "m"(idtr)); // load the new IDT
- __asm__ volatile("sti"); // set the interrupt flag
- barrier();
+ 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);
- PIC_init();
-}
+ 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);
-void PIC_sendEOI(unsigned char irq) {
- if (irq >= 8)
- outb(PIC2_COMMAND, PIC_EOI);
+ barrier();
+ __asm__ volatile("lidt %0"
+ :
+ : "m"(idtr)); // load the new IDT
+ __asm__ volatile("sti"); // set the interrupt flag
+ barrier();
- outb(PIC1_COMMAND, PIC_EOI);
-}
-
-void PIC_init() {
- unsigned char a1, a2;
-
- a1 = inb(PIC1_DATA); // save masks
- a2 = inb(PIC2_DATA);
-
- outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); // starts the initialization sequence (in cascade mode)
- io_wait();
- outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4);
- io_wait();
- outb(PIC1_DATA, PIC1_OFFSET); // ICW2: Master PIC vector offset
- io_wait();
- outb(PIC2_DATA, PIC2_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)
- io_wait();
- outb(PIC2_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)
- io_wait();
- outb(PIC2_DATA, ICW4_8086);
- io_wait();
-
- outb(PIC1_DATA, a1); // restore saved masks.
- outb(PIC2_DATA, a2);
-}
-void IRQ_set_mask(unsigned char IRQline) {
- uint16_t port;
- uint8_t value;
-
- if (IRQline < 8) {
- port = PIC1_DATA;
- } else {
- port = PIC2_DATA;
- IRQline -= 8;
+ PIC_init();
}
- value = inb(port) | (1 << IRQline);
- outb(port, value);
-}
-void IRQ_clear_mask(unsigned char IRQline) {
- uint16_t port;
- uint8_t value;
+ void PIC_sendEOI(unsigned char irq) {
+ if (irq >= 8)
+ outb(kPIC2_COMMAND, kPIC_EOI);
- if (IRQline < 8) {
- port = PIC1_DATA;
- } else {
- port = PIC2_DATA;
- IRQline -= 8;
+ outb(kPIC1_COMMAND, kPIC_EOI);
+ }
+
+ void PIC_init() {
+ unsigned char a1, a2;
+
+ a1 = inb(kPIC1_DATA); // save masks
+ a2 = inb(kPIC2_DATA);
+
+ outb(kPIC1_COMMAND, kICW1_INIT | kICW1_ICW4); // starts the initialization sequence (in cascade mode)
+ io_wait();
+ outb(kPIC2_COMMAND, kICW1_INIT | kICW1_ICW4);
+ io_wait();
+ outb(kPIC1_DATA, kPIC1_OFFSET); // ICW2: Master PIC vector offset
+ io_wait();
+ outb(kPIC2_DATA, kPIC2_OFFSET); // ICW2: Slave PIC vector offset
+ io_wait();
+ outb(kPIC1_DATA, 4); // ICW3: tell Master PIC that there is a slave PIC at IRQ2 (0000 0100)
+ io_wait();
+ outb(kPIC2_DATA, 2); // ICW3: tell Slave PIC its cascade identity (0000 0010)
+ io_wait();
+
+ outb(kPIC1_DATA, kICW4_8086); // ICW4: have the PICs use 8086 mode (and not 8080 mode)
+ io_wait();
+ outb(kPIC2_DATA, kICW4_8086);
+ io_wait();
+
+ 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 = kPIC1_DATA;
+ } else {
+ port = kPIC2_DATA;
+ IRQline -= 8;
+ }
+ value = inb(port) | (1 << IRQline);
+ outb(port, value);
+ }
+
+ void IRQ_clear_mask(unsigned char IRQline) {
+ uint16_t port;
+ uint8_t value;
+
+ if (IRQline < 8) {
+ port = kPIC1_DATA;
+ } else {
+ port = kPIC2_DATA;
+ IRQline -= 8;
+ }
+ value = inb(port) & ~(1 << IRQline);
+ outb(port, value);
}
- value = inb(port) & ~(1 << IRQline);
- outb(port, value);
-}
-/* Helper func */
-static uint16_t __pic_get_irq_reg(int ocw3) {
- /* OCW3 to PIC CMD to get the register values. PIC2 is chained, and
+ /* Helper func */
+ 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);
-}
-
-/* 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);
-}
-
-/* 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);
-}
-
-static int_handler_t handlers[256];
-static void *handlers_args[256];
-
-extern "C" void pic1_irq_real_0(TaskFrame *frame) {
- timer_tick();
- Scheduler::switch_task(frame);
- PIC_sendEOI(0);
-}
-extern "C" void pic1_irq_real_1() {
- PIC_sendEOI(1);
-}
-extern "C" void pic1_irq_real_2() {
- _hcf();
- PIC_sendEOI(2);
-}
-extern "C" void pic1_irq_real_3() {
- PIC_sendEOI(3);
-}
-extern "C" void pic1_irq_real_4() {
- if (handlers[4] != nullptr) {
- handlers[4](handlers_args[4]);
- }
- PIC_sendEOI(4);
-}
-extern "C" void pic1_irq_real_5() {
- PIC_sendEOI(5);
-}
-extern "C" void pic1_irq_real_6() {
- PIC_sendEOI(6);
-}
-extern "C" void pic1_irq_real_7() {
- int irr = pic_get_irr();
- if (!(irr & 0x80)) return;
- PIC_sendEOI(7);
-}
-
-extern "C" void pic2_irq_real_0() {
- PIC_sendEOI(8);
-}
-extern "C" void pic2_irq_real_1() {
- PIC_sendEOI(9);
-}
-extern "C" void pic2_irq_real_2() {
- PIC_sendEOI(10);
-}
-extern "C" void pic2_irq_real_3() {
- PIC_sendEOI(11);
-}
-extern "C" void pic2_irq_real_4() {
- PIC_sendEOI(12);
-}
-extern "C" void pic2_irq_real_5() {
- PIC_sendEOI(13);
-}
-extern "C" void pic2_irq_real_6() {
- PIC_sendEOI(14);
-}
-extern "C" void pic2_irq_real_7() {
- // Probaby wrong
- int irr = pic_get_irr();
- if (!(irr & (0x80 << 8))) {
- outb(PIC1_COMMAND, PIC_EOI);
- return;
+ outb(kPIC1_COMMAND, ocw3);
+ outb(kPIC2_COMMAND, ocw3);
+ return (inb(kPIC2_COMMAND) << 8) | inb(kPIC1_COMMAND);
}
- PIC_sendEOI(15);
-}
+ /* Returns the combined value of the cascaded PICs irq request register */
+ uint16_t pic_get_irr(void) {
+ 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(kPIC_READ_ISR);
+ }
+
+ static int_handler_t handlers[256];
+ static void *handlers_args[256];
+
+ // 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);
+ }
+ extern "C" void pic1_irq_real_1() {
+ PIC_sendEOI(1);
+ }
+ extern "C" void pic1_irq_real_2() {
+ _hcf();
+ PIC_sendEOI(2);
+ }
+ extern "C" void pic1_irq_real_3() {
+ PIC_sendEOI(3);
+ }
+ extern "C" __attribute__((force_align_arg_pointer)) void pic1_irq_real_4() {
+ if (handlers[4] != nullptr) {
+ handlers[4](handlers_args[4]);
+ }
+ PIC_sendEOI(4);
+ }
+ extern "C" void pic1_irq_real_5() {
+ PIC_sendEOI(5);
+ }
+ extern "C" void pic1_irq_real_6() {
+ PIC_sendEOI(6);
+ }
+ extern "C" void pic1_irq_real_7() {
+ int irr = pic_get_irr();
+ if (!(irr & 0x80)) return;
+ PIC_sendEOI(7);
+ }
+
+ extern "C" void pic2_irq_real_0() {
+ PIC_sendEOI(8);
+ }
+ extern "C" void pic2_irq_real_1() {
+ PIC_sendEOI(9);
+ }
+ extern "C" void pic2_irq_real_2() {
+ PIC_sendEOI(10);
+ }
+ extern "C" void pic2_irq_real_3() {
+ PIC_sendEOI(11);
+ }
+ extern "C" void pic2_irq_real_4() {
+ PIC_sendEOI(12);
+ }
+ extern "C" void pic2_irq_real_5() {
+ PIC_sendEOI(13);
+ }
+ extern "C" void pic2_irq_real_6() {
+ PIC_sendEOI(14);
+ }
+ extern "C" void pic2_irq_real_7() {
+ // Probaby wrong
+ int irr = pic_get_irr();
+ if (!(irr & (0x80 << 8))) {
+ 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;
-}
\ No newline at end of file
+ Arch::IDT::handlers[num] = handler;
+ Arch::IDT::handlers_args[num] = firstarg;
+}
diff --git a/src/arch/x86/idt.hpp b/src/arch/x86/idt.hpp
index d5c2c65cb..183192a5e 100644
--- a/src/arch/x86/idt.hpp
+++ b/src/arch/x86/idt.hpp
@@ -1,96 +1,68 @@
#ifndef OS1_IDT_H
#define OS1_IDT_H
-#include
-#include
+#include
+#include
-#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();
-void IRQ_set_mask(unsigned char IRQline);
-void IRQ_clear_mask(unsigned char IRQline);
-uint16_t pic_get_irr(void);
-uint16_t pic_get_isr(void);
+ void PIC_sendEOI(unsigned char irq);
+ void PIC_init();
+ void IRQ_set_mask(unsigned char IRQline);
+ void IRQ_clear_mask(unsigned char IRQline);
+ uint16_t pic_get_irr(void);
+ uint16_t pic_get_isr(void);
-typedef struct {
- 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
- uint8_t attributes; // Type and attributes; see the IDT page
- 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;
+ 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
+ uint8_t attributes; // Type and attributes; see the IDT page
+ 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));
-typedef struct {
- uint16_t limit;
- uint64_t base;
-} __attribute__((packed)) idtr_t;
+ struct Idtr {
+ uint16_t limit;
+ uint64_t base;
+ } __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
+ extern "C" void exception_handler_err(uint64_t code);
+ extern "C" void exception_handler_no_err(void);
- uint64_t r15;
- uint64_t r14;
- uint64_t r13;
- uint64_t r12;
- uint64_t r11;
- uint64_t r10;
- uint64_t r9;
- uint64_t r8;
+ void idt_set_descriptor(uint8_t vector, void (*isr)(), uint8_t flags);
- uint64_t rdi;
- uint64_t rsi;
- uint64_t rbp;
- uint64_t rbx;
- uint64_t rdx;
- uint64_t rcx;
- uint64_t rax;
+ void idt_init();
- uint64_t ip;
- uint64_t cs;
- uint64_t flags;
- uint64_t sp;
- uint64_t ss;
-}
-__attribute__((packed));
-
-extern "C" void exception_handler(void);
-
-void idt_set_descriptor(uint8_t vector, void (*isr)(), uint8_t flags);
-
-void idt_init(void);
-
-extern void (*isr_stub_table[])();
+ extern "C" void (*isr_stub_table[])();
+} // namespace Arch::IDT
using int_handler_t = void (*)(void *);
diff --git a/src/arch/x86/memman.hpp b/src/arch/x86/memman.hpp
index bf00f664e..df73e6c94 100644
--- a/src/arch/x86/memman.hpp
+++ b/src/arch/x86/memman.hpp
@@ -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);
diff --git a/src/arch/x86/task.cpp b/src/arch/x86/task.cpp
index 6115ca3a9..9843c392c 100644
--- a/src/arch/x86/task.cpp
+++ b/src/arch/x86/task.cpp
@@ -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(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);
diff --git a/src/arch/x86/task.hpp b/src/arch/x86/task.hpp
index bdb5dbf53..b65647d80 100644
--- a/src/arch/x86/task.hpp
+++ b/src/arch/x86/task.hpp
@@ -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 _used_time;
@@ -102,7 +103,7 @@ namespace Scheduler {
void unblock(List::Node *what);
void unblock_nolock(List::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> getTaskTimePerPid();
diff --git a/src/arch/x86/task_arch.hpp b/src/arch/x86/task_arch.hpp
new file mode 100644
index 000000000..fc7cf2edd
--- /dev/null
+++ b/src/arch/x86/task_arch.hpp
@@ -0,0 +1,44 @@
+//
+// Created by Stepan Usatiuk on 01.04.2024.
+//
+
+#ifndef FICUS_TASK_ARCH_HPP
+#define FICUS_TASK_ARCH_HPP
+
+#include
+
+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
diff --git a/src/arch/x86/timer.cpp b/src/arch/x86/timer.cpp
index a78e0f121..73f3d4265 100644
--- a/src/arch/x86/timer.cpp
+++ b/src/arch/x86/timer.cpp
@@ -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() {