pretty up GDT a little, and other stuff

also thanks internet for the boilerplate
This commit is contained in:
2024-03-22 15:38:51 +01:00
parent d9de8e45a0
commit 02ec0c6105
82 changed files with 974 additions and 864 deletions

View File

@@ -2,7 +2,26 @@
BasedOnStyle: LLVM BasedOnStyle: LLVM
AccessModifierOffset: -4 AccessModifierOffset: -4
AlignAfterOpenBracket: Align AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: None AlignConsecutiveAssignments:
Enabled: true
AcrossEmptyLines: true
AcrossComments: false
AlignConsecutiveBitFields:
Enabled: true
AcrossEmptyLines: true
AcrossComments: true
AlignConsecutiveDeclarations:
Enabled: true
AcrossEmptyLines: true
AcrossComments: false
AlignConsecutiveMacros:
Enabled: true
AcrossEmptyLines: true
AcrossComments: false
AlignTrailingComments:
Kind: Always
OverEmptyLines: 2
SpacesBeforeTrailingComments: 1
AlignOperands: Align AlignOperands: Align
AlignEscapedNewlines: Right AlignEscapedNewlines: Right
AllowAllArgumentsOnNextLine: false AllowAllArgumentsOnNextLine: false
@@ -57,7 +76,6 @@ SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: false SpaceBeforeRangeBasedForLoopColon: false
SpaceInEmptyParentheses: false SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 0
SpacesInAngles: false SpacesInAngles: false
SpacesInCStyleCastParentheses: false SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false SpacesInContainerLiterals: false

View File

@@ -7,7 +7,7 @@
#include "idt.hpp" #include "idt.hpp"
#include "io.hpp" #include "io.hpp"
#define PORT 0x3f8// COM1 #define PORT 0x3f8 // COM1
void SerialTty::putchar(char c) { void SerialTty::putchar(char c) {
LockGuard guard(mutex); LockGuard guard(mutex);
@@ -27,7 +27,7 @@ void SerialTty::this_pooler() {
mutex.lock(); mutex.lock();
while (true) { while (true) {
bool read_something = false; bool read_something = false;
int r = read(); int r = read();
while (r != -1) { while (r != -1) {
read_something = true; read_something = true;
buf.push_back((char) r); buf.push_back((char) r);
@@ -41,10 +41,10 @@ void SerialTty::this_pooler() {
} }
SerialTty::SerialTty() : Tty() { SerialTty::SerialTty() : Tty() {
outb(PORT + 3, 0x00);// Disable DLAB outb(PORT + 3, 0x00); // Disable DLAB
outb(PORT + 1, 0x01);// Enable data available interrupt outb(PORT + 1, 0x01); // Enable data available interrupt
Task *task = new_ktask((void (*)(void))(&SerialTty::this_pooler), "serialpooler", false); Task *task = new_ktask((void (*)(void))(&SerialTty::this_pooler), "serialpooler", false);
task->frame.rdi = reinterpret_cast<uint64_t>(this); task->frame.rdi = reinterpret_cast<uint64_t>(this);
start_task(task); start_task(task);

View File

@@ -11,13 +11,13 @@
class SerialTty : public Tty { class SerialTty : public Tty {
// TODO: Possibly there should be 2 mutexes? // TODO: Possibly there should be 2 mutexes?
Mutex mutex; Mutex mutex;
CV readercv; CV readercv;
CV isrcv; CV isrcv;
static void isr(void *tty); static void isr(void *tty);
void this_isr(); void this_isr();
void this_pooler(); void this_pooler();
CircularBuffer<char, 512> buf; CircularBuffer<char, 512> buf;
public: public:
@@ -28,4 +28,4 @@ public:
}; };
#endif//OS2_SERIALTTY_HPP #endif //OS2_SERIALTTY_HPP

View File

@@ -38,7 +38,7 @@ real_start() {
extern "C" void _start(void) { extern "C" void _start(void) {
_sse_setup(); _sse_setup();
barrier(); barrier();
gdt_setup(); Arch::GDT::gdt_setup();
barrier(); barrier();
idt_init(); idt_init();
barrier(); barrier();
@@ -71,9 +71,9 @@ extern "C" void _start(void) {
KERN_AddressSpace->map((void *) (kernel_virt_base + i * PAGE_SIZE), (void *) (kernel_phys_base + i * PAGE_SIZE), PAGE_RW | PAGE_USER); KERN_AddressSpace->map((void *) (kernel_virt_base + i * PAGE_SIZE), (void *) (kernel_phys_base + i * PAGE_SIZE), PAGE_RW | PAGE_USER);
} }
uint64_t real_new_cr3 = (uint64_t) HHDM_V2P(KERN_AddressSpace_PML4); uint64_t real_new_cr3 = (uint64_t) HHDM_V2P(KERN_AddressSpace_PML4);
uint64_t *new_stack_top = &KERN_stack[KERN_STACK_SIZE - 1]; // Don't forget in which direction the stack grows... uint64_t *new_stack_top = &KERN_stack[KERN_STACK_SIZE - 1]; // Don't forget in which direction the stack grows...
new_stack_top = reinterpret_cast<uint64_t *>(((uint64_t) new_stack_top) & (~0xFULL));// correct alignment for sse new_stack_top = reinterpret_cast<uint64_t *>(((uint64_t) new_stack_top) & (~0xFULL)); // correct alignment for sse
barrier(); barrier();
__asm__ volatile("movq %[new_stack_top], %%rsp; movq %[real_new_cr3], %%cr3; call real_start" __asm__ volatile("movq %[new_stack_top], %%rsp; movq %[real_new_cr3], %%cr3; call real_start"

View File

@@ -74,16 +74,19 @@ gdt_code_user:
db PRESENT | USER | NOT_SYS | EXEC | RW ; Access db PRESENT | USER | NOT_SYS | EXEC | RW ; Access
db GRAN_4K | LONG_MODE | 0xF ; Flags & Limit (high, bits 16-19) db GRAN_4K | LONG_MODE | 0xF ; Flags & Limit (high, bits 16-19)
db 0 ; Base (high, bits 24-31) db 0 ; Base (high, bits 24-31)
global gdt_tss:data global gdt_tss:data
gdt_tss: gdt_tss:
dq 0x00000000 ;TODO dq 0x00000000
dq 0x00000000 dq 0x00000000
global gdt_tss_user:data global gdt_tss_user:data
gdt_tss_user: gdt_tss_user:
dq 0x00000000 ;TODO
dq 0x00000000 dq 0x00000000
dq 0x00000000
global gdt_end:data global gdt_end:data
gdt_end: gdt_end:
global gdtr:data global gdtr:data
gdtr: gdtr:
dw gdt_end - gdt_null - 1 dw gdt_end - gdt_null - 1
@@ -93,20 +96,23 @@ section .text
global _gdt_setup:function (_gdt_setup.end - _gdt_setup) global _gdt_setup:function (_gdt_setup.end - _gdt_setup)
_gdt_setup: _gdt_setup:
LGDT [gdtr] LGDT [gdtr]
; Reload CS register: ; Reload CS register
PUSH (gdt_code - gdt_null); Push code segment to stack, 0x08 is a stand-in for your code segment PUSH (gdt_code - gdt_null) ; Push code segment to stack
LEA RAX, [rel .flush] ; Load address of .reload_CS into RAX LEA RAX, [rel .flush] ; Load address of .flush into RAX
PUSH RAX ; Push this value to the stack PUSH RAX ; Push this value to the stack
RETFQ ; Perform a far return, RETFQ or LRETQ depending on syntax RETFQ ; Perform a far return, RETFQ or LRETQ depending on syntax
.flush: .flush:
; Reload data segment registers ; Reload data segment registers
MOV AX, (gdt_data - gdt_null) ; 0x10 is a stand-in for your data segment MOV AX, (gdt_data - gdt_null)
MOV DS, AX MOV DS, AX
MOV ES, AX MOV ES, AX
MOV FS, AX MOV FS, AX
MOV GS, AX MOV GS, AX
MOV SS, AX MOV SS, AX
MOV AX, (gdt_tss - gdt_null) MOV AX, (gdt_tss - gdt_null)
ltr AX ltr AX
RET RET
.end: .end:

View File

@@ -3,37 +3,45 @@
// //
#include "gdt.hpp" #include "gdt.hpp"
#include "asserts.hpp"
#include "misc.hpp" #include "misc.hpp"
#include <cstddef>
namespace Arch::GDT {
static tss_entry_struct tss_entry;
static tss_entry_struct tss_entry_user;
static struct tss_entry_struct tss_entry; static constexpr size_t INT_STACK_SIZE = 16384;
static struct tss_entry_struct tss_entry_user; static constexpr size_t RSP_STACK_SIZE = 16384;
#define INT_STACK_SIZE 16384 static uint64_t int_stack[INT_STACK_SIZE];
#define RSP_STACK_SIZE 16384 static uint64_t rsp_stack[RSP_STACK_SIZE];
static uint64_t int_stack[INT_STACK_SIZE];
static uint64_t rsp_stack[RSP_STACK_SIZE];
void gdt_setup() { //
uint32_t tss_limit = sizeof(tss_entry); void gdt_setup() {
uint64_t tss_base = (uint64_t) &tss_entry; uint32_t tss_limit = sizeof(tss_entry);
uint64_t tss_base = (uint64_t) &tss_entry;
gdt_tss.limit_low = tss_limit & 0xFFFF; gdt_tss.limit_low = tss_limit & 0xFFFF;
gdt_tss.base_low = tss_base & 0xFFFFFF; gdt_tss.base_low = tss_base & 0xFFFFFF;
gdt_tss.type = 0b1001;// Available 64 bit TSS gdt_tss.type = 0b1001; // Available 64 bit TSS
gdt_tss.zero = 0; gdt_tss.zero = 0;
gdt_tss.DPL = 0; gdt_tss.DPL = 0;
gdt_tss.present = 1; gdt_tss.present = 1;
gdt_tss.limit_high = (tss_limit >> 16) & 0xF; gdt_tss.limit_high = (tss_limit >> 16) & 0xF;
gdt_tss.available = 0; gdt_tss.available = 0;
gdt_tss.unused = 0; gdt_tss.unused = 0;
gdt_tss.gran = 0; gdt_tss.gran = 0;
gdt_tss.base_high = (tss_base >> 24) & 0xFFFFFFFFFF; gdt_tss.base_high = (tss_base >> 24) & 0xFFFFFFFFFF;
tss_entry.ist1 = (((uintptr_t) int_stack + (INT_STACK_SIZE - 9) - 1) & (~0xFULL)) + 8; tss_entry.ist1 = (((uintptr_t) int_stack + (INT_STACK_SIZE - 9) - 1) & (~0xFULL)) + 8;
if ((tss_entry.ist1 & 0xFULL) != 8) _hcf(); assert((tss_entry.ist1 & 0xFULL) == 8);
tss_entry.rsp0 = (((uintptr_t) rsp_stack + (RSP_STACK_SIZE - 9) - 1) & (~0xFULL)) + 8;
if ((tss_entry.rsp0 & 0xFULL) != 8) _hcf();
barrier();// The asm function might clobber registers tss_entry.rsp0 = (((uintptr_t) rsp_stack + (RSP_STACK_SIZE - 9) - 1) & (~0xFULL)) + 8;
_gdt_setup(); assert((tss_entry.rsp0 & 0xFULL) == 8);
}
barrier(); // The asm function might clobber registers
_gdt_setup();
barrier();
}
} // namespace Arch::GDT

View File

@@ -3,78 +3,89 @@
#include <cstdint> #include <cstdint>
struct gdt_entry_bits { namespace Arch::GDT {
unsigned int limit_low : 16; struct gdt_entry_bits {
unsigned int base_low : 24; unsigned int limit_low : 16;
unsigned int accessed : 1; unsigned int base_low : 24;
unsigned int read_write : 1; // readable for code, writable for data unsigned int accessed : 1;
unsigned int conforming_expand_down : 1;// conforming for code, expand down for data unsigned int read_write : 1; // readable for code, writable for data
unsigned int code : 1; // 1 for code, 0 for data unsigned int conforming_expand_down : 1; // conforming for code, expand down for data
unsigned int code_data_segment : 1; // should be 1 for everything but TSS and LDT unsigned int code : 1; // 1 for code, 0 for data
unsigned int DPL : 2; // privilege level unsigned int code_data_segment : 1; // should be 1 for everything but TSS and LDT
unsigned int present : 1; unsigned int DPL : 2; // privilege level
unsigned int limit_high : 4; unsigned int present : 1;
unsigned int available : 1;// only used in software; has no effect on hardware unsigned int limit_high : 4;
unsigned int long_mode : 1; unsigned int available : 1; // only used in software; has no effect on hardware
unsigned int big : 1; // 32-bit opcodes for code, uint32_t stack for data unsigned int long_mode : 1;
unsigned int gran : 1;// 1 to use 4k page addressing, 0 for byte addressing unsigned int big : 1; // 32-bit opcodes for code, uint32_t stack for data
unsigned int base_high : 8; unsigned int gran : 1; // 1 to use 4k page addressing, 0 for byte addressing
} __attribute__((packed)); unsigned int base_high : 8;
struct gdt_tss_entry_bits { //
unsigned int limit_low : 16; uint64_t selector() volatile;
unsigned int base_low : 24; } __attribute__((packed));
unsigned int type : 4;
unsigned int zero : 1;
unsigned int DPL : 2;
unsigned int present : 1;
unsigned int limit_high : 4;
unsigned int available : 1;
unsigned int unused : 2;
unsigned int gran : 1;
uint64_t base_high : 40;
unsigned int zeros : 32;
} __attribute__((packed));
struct tss_entry_struct { struct gdt_tss_entry_bits {
uint32_t reserved; unsigned int limit_low : 16;
uint64_t rsp0; unsigned int base_low : 24;
uint64_t rsp1; unsigned int type : 4;
uint64_t rsp2; unsigned int zero : 1;
uint64_t reserved2; unsigned int DPL : 2;
uint64_t ist1; unsigned int present : 1;
uint64_t ist2; unsigned int limit_high : 4;
uint64_t ist3; unsigned int available : 1;
uint64_t ist4; unsigned int unused : 2;
uint64_t ist5; unsigned int gran : 1;
uint64_t ist6; uint64_t base_high : 40;
uint64_t ist7; unsigned int zeros : 32;
uint64_t reserved3; } __attribute__((packed));
uint32_t reserved4;
} __attribute__((packed));
extern "C" void _gdt_setup(); struct tss_entry_struct {
void gdt_setup(); uint32_t reserved;
uint64_t rsp0;
uint64_t rsp1;
uint64_t rsp2;
uint64_t reserved2;
uint64_t ist1;
uint64_t ist2;
uint64_t ist3;
uint64_t ist4;
uint64_t ist5;
uint64_t ist6;
uint64_t ist7;
uint64_t reserved3;
uint32_t reserved4;
} __attribute__((packed));
extern volatile struct gdt_entry_bits gdt_null; void gdt_setup();
extern volatile struct gdt_entry_bits gdt_code_16;
extern volatile struct gdt_entry_bits gdt_data_16;
extern volatile struct gdt_entry_bits gdt_code_32;
extern volatile struct gdt_entry_bits gdt_data_32;
extern volatile struct gdt_entry_bits gdt_code;
extern volatile struct gdt_entry_bits gdt_data;
extern volatile struct gdt_entry_bits gdt_code_user;
extern volatile struct gdt_entry_bits gdt_data_user;
extern volatile struct gdt_tss_entry_bits gdt_tss;
extern volatile struct gdt_tss_entry_bits gdt_tss_user;
extern volatile struct gdt_entry_bits gdt_end;/// It is not a pointer! extern "C" {
void _gdt_setup();
extern volatile struct gdt_entry_bits gdt_null;
extern volatile struct gdt_entry_bits gdt_code_16;
extern volatile struct gdt_entry_bits gdt_data_16;
extern volatile struct gdt_entry_bits gdt_code_32;
extern volatile struct gdt_entry_bits gdt_data_32;
extern volatile struct gdt_entry_bits gdt_code;
extern volatile struct gdt_entry_bits gdt_data;
extern volatile struct gdt_entry_bits gdt_code_user;
extern volatile struct gdt_entry_bits gdt_data_user;
extern volatile struct gdt_tss_entry_bits gdt_tss;
extern volatile struct gdt_tss_entry_bits gdt_tss_user;
extern struct { extern volatile struct gdt_entry_bits gdt_end; // It is not a pointer!
uint16_t limit;
uint64_t base; extern struct {
} gdtr; uint16_t limit;
uint64_t base;
} __attribute__((packed)) gdtr;
}
inline uint64_t gdt_entry_bits::selector() volatile {
return (((uint64_t) this) - ((uint64_t) &gdt_null));
}
} // namespace Arch::GDT
#define GDTSEL(x) (((uint64_t) &x) - ((uint64_t) &gdt_null))
#endif #endif

View File

@@ -12,4 +12,4 @@ extern uint64_t KERN_stack[KERN_STACK_SIZE] __attribute__((aligned(16)));
#define TASK_POINTER 0x10000 #define TASK_POINTER 0x10000
#endif//OS1_GLOBALS_H #endif //OS1_GLOBALS_H

View File

@@ -7,10 +7,10 @@
#include "task.hpp" #include "task.hpp"
#include "timer.hpp" #include "timer.hpp"
__attribute__((aligned(0x10))) static idt_entry_t idt[256];// Create an array of IDT entries; aligned for performance __attribute__((aligned(0x10))) static idt_entry_t idt[256]; // Create an array of IDT entries; aligned for performance
static idtr_t idtr; static idtr_t idtr;
extern "C" __attribute__((noreturn)) void exception_handler(void) { extern "C" __attribute__((noreturn)) void exception_handler(void) {
_hcf(); _hcf();
} }
@@ -33,20 +33,20 @@ extern "C" void pic2_irq_6();
extern "C" void pic2_irq_7(); extern "C" void pic2_irq_7();
void idt_set_descriptor(uint8_t vector, void (*isr)(), uint8_t flags) { void idt_set_descriptor(uint8_t vector, void (*isr)(), uint8_t flags) {
idt_entry_t *descriptor = &idt[vector]; idt_entry_t *descriptor = &idt[vector];
descriptor->isr_low = (uint64_t) isr & 0xFFFF; descriptor->isr_low = (uint64_t) isr & 0xFFFF;
descriptor->kernel_cs = GDTSEL(gdt_code); descriptor->kernel_cs = Arch::GDT::gdt_code.selector();
descriptor->ist = 1; descriptor->ist = 1;
descriptor->attributes = flags; descriptor->attributes = flags;
descriptor->isr_mid = ((uint64_t) isr >> 16) & 0xFFFF; descriptor->isr_mid = ((uint64_t) isr >> 16) & 0xFFFF;
descriptor->isr_high = ((uint64_t) isr >> 32) & 0xFFFFFFFF; descriptor->isr_high = ((uint64_t) isr >> 32) & 0xFFFFFFFF;
descriptor->reserved = 0; descriptor->reserved = 0;
} }
void idt_init() { void idt_init() {
idtr.base = (uintptr_t) &idt[0]; idtr.base = (uintptr_t) &idt[0];
idtr.limit = (uint16_t) ((uint64_t) &idt[255] - (uint64_t) &idt[0]); idtr.limit = (uint16_t) ((uint64_t) &idt[255] - (uint64_t) &idt[0]);
for (uint8_t vector = 0; vector < 32; vector++) { for (uint8_t vector = 0; vector < 32; vector++) {
@@ -74,8 +74,8 @@ void idt_init() {
barrier(); barrier();
__asm__ volatile("lidt %0" __asm__ volatile("lidt %0"
: :
: "m"(idtr));// load the new IDT : "m"(idtr)); // load the new IDT
__asm__ volatile("sti"); // set the interrupt flag __asm__ volatile("sti"); // set the interrupt flag
barrier(); barrier();
PIC_init(); PIC_init();
@@ -91,33 +91,33 @@ void PIC_sendEOI(unsigned char irq) {
void PIC_init() { void PIC_init() {
unsigned char a1, a2; unsigned char a1, a2;
a1 = inb(PIC1_DATA);// save masks a1 = inb(PIC1_DATA); // save masks
a2 = inb(PIC2_DATA); a2 = inb(PIC2_DATA);
outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4);// starts the initialization sequence (in cascade mode) outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); // starts the initialization sequence (in cascade mode)
io_wait(); io_wait();
outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4); outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4);
io_wait(); io_wait();
outb(PIC1_DATA, PIC1_OFFSET);// ICW2: Master PIC vector offset outb(PIC1_DATA, PIC1_OFFSET); // ICW2: Master PIC vector offset
io_wait(); io_wait();
outb(PIC2_DATA, PIC2_OFFSET);// ICW2: Slave PIC vector offset outb(PIC2_DATA, PIC2_OFFSET); // ICW2: Slave PIC vector offset
io_wait(); io_wait();
outb(PIC1_DATA, 4);// ICW3: tell Master PIC that there is a slave PIC at IRQ2 (0000 0100) outb(PIC1_DATA, 4); // ICW3: tell Master PIC that there is a slave PIC at IRQ2 (0000 0100)
io_wait(); io_wait();
outb(PIC2_DATA, 2);// ICW3: tell Slave PIC its cascade identity (0000 0010) outb(PIC2_DATA, 2); // ICW3: tell Slave PIC its cascade identity (0000 0010)
io_wait(); io_wait();
outb(PIC1_DATA, ICW4_8086);// ICW4: have the PICs use 8086 mode (and not 8080 mode) outb(PIC1_DATA, ICW4_8086); // ICW4: have the PICs use 8086 mode (and not 8080 mode)
io_wait(); io_wait();
outb(PIC2_DATA, ICW4_8086); outb(PIC2_DATA, ICW4_8086);
io_wait(); io_wait();
outb(PIC1_DATA, a1);// restore saved masks. outb(PIC1_DATA, a1); // restore saved masks.
outb(PIC2_DATA, a2); outb(PIC2_DATA, a2);
} }
void IRQ_set_mask(unsigned char IRQline) { void IRQ_set_mask(unsigned char IRQline) {
uint16_t port; uint16_t port;
uint8_t value; uint8_t value;
if (IRQline < 8) { if (IRQline < 8) {
port = PIC1_DATA; port = PIC1_DATA;
@@ -131,7 +131,7 @@ void IRQ_set_mask(unsigned char IRQline) {
void IRQ_clear_mask(unsigned char IRQline) { void IRQ_clear_mask(unsigned char IRQline) {
uint16_t port; uint16_t port;
uint8_t value; uint8_t value;
if (IRQline < 8) { if (IRQline < 8) {
port = PIC1_DATA; port = PIC1_DATA;
@@ -164,9 +164,9 @@ uint16_t pic_get_isr(void) {
} }
static int_handler_t handlers[256]; static int_handler_t handlers[256];
static void *handlers_args[256]; static void *handlers_args[256];
extern "C" void pic1_irq_real_0(struct task_frame *frame) { extern "C" void pic1_irq_real_0(struct task_frame *frame) {
timer_tick(); timer_tick();
switch_task(frame); switch_task(frame);
PIC_sendEOI(0); PIC_sendEOI(0);
@@ -232,6 +232,6 @@ extern "C" void pic2_irq_real_7() {
} }
void attach_interrupt(unsigned num, int_handler_t handler, void *firstarg) { void attach_interrupt(unsigned num, int_handler_t handler, void *firstarg) {
handlers[num] = handler; handlers[num] = handler;
handlers_args[num] = firstarg; handlers_args[num] = firstarg;
} }

View File

@@ -4,47 +4,47 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#define PIC1 0x20 /* IO base address for master PIC */ #define PIC1 0x20 /* IO base address for master PIC */
#define PIC2 0xA0 /* IO base address for slave PIC */ #define PIC2 0xA0 /* IO base address for slave PIC */
#define PIC1_COMMAND PIC1 #define PIC1_COMMAND PIC1
#define PIC1_DATA (PIC1 + 1) #define PIC1_DATA (PIC1 + 1)
#define PIC2_COMMAND PIC2 #define PIC2_COMMAND PIC2
#define PIC2_DATA (PIC2 + 1) #define PIC2_DATA (PIC2 + 1)
#define PIC_EOI 0x20 /* End-of-interrupt command code */ #define PIC_EOI 0x20 /* End-of-interrupt command code */
#define ICW1_ICW4 0x01 /* Indicates that ICW4 will be present */ #define ICW1_ICW4 0x01 /* Indicates that ICW4 will be present */
#define ICW1_SINGLE 0x02 /* Single (cascade) mode */ #define ICW1_SINGLE 0x02 /* Single (cascade) mode */
#define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */ #define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */
#define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */ #define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */
#define ICW1_INIT 0x10 /* Initialization - required! */ #define ICW1_INIT 0x10 /* Initialization - required! */
#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */ #define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */
#define ICW4_AUTO 0x02 /* Auto (normal) EOI */ #define ICW4_AUTO 0x02 /* Auto (normal) EOI */
#define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */ #define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */
#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */ #define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */
#define ICW4_SFNM 0x10 /* Special fully nested (not) */ #define ICW4_SFNM 0x10 /* Special fully nested (not) */
#define PIC_READ_IRR 0x0a /* OCW3 irq ready next CMD read */ #define PIC_READ_IRR 0x0a /* OCW3 irq ready next CMD read */
#define PIC_READ_ISR 0x0b /* OCW3 irq service next CMD read */ #define PIC_READ_ISR 0x0b /* OCW3 irq service next CMD read */
#define PIC1_OFFSET 0x20 #define PIC1_OFFSET 0x20
#define PIC2_OFFSET 0x28 #define PIC2_OFFSET 0x28
void PIC_sendEOI(unsigned char irq); void PIC_sendEOI(unsigned char irq);
void PIC_init(); void PIC_init();
void IRQ_set_mask(unsigned char IRQline); void IRQ_set_mask(unsigned char IRQline);
void IRQ_clear_mask(unsigned char IRQline); void IRQ_clear_mask(unsigned char IRQline);
uint16_t pic_get_irr(void); uint16_t pic_get_irr(void);
uint16_t pic_get_isr(void); uint16_t pic_get_isr(void);
typedef struct { typedef struct {
uint16_t isr_low; // The lower 16 bits of the ISR's address 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 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 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 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 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 isr_high; // The higher 32 bits of the ISR's address
uint32_t reserved; // Set to zero uint32_t reserved; // Set to zero
} __attribute__((packed)) idt_entry_t; } __attribute__((packed)) idt_entry_t;
typedef struct { typedef struct {
@@ -57,7 +57,7 @@ typedef struct {
// Assuming the compiler understands that this is pushed on the stack in the correct order // Assuming the compiler understands that this is pushed on the stack in the correct order
struct task_frame { struct task_frame {
uint64_t guard; uint64_t guard;
uint64_t guard2;// To keep stack aligned after pushaq uint64_t guard2; // To keep stack aligned after pushaq
uint64_t r15; uint64_t r15;
uint64_t r14; uint64_t r14;
@@ -84,16 +84,16 @@ struct task_frame {
} __attribute__((packed)); } __attribute__((packed));
extern "C" void exception_handler(void); extern "C" void exception_handler(void);
void idt_set_descriptor(uint8_t vector, void (*isr)(), uint8_t flags); void idt_set_descriptor(uint8_t vector, void (*isr)(), uint8_t flags);
void idt_init(void); void idt_init(void);
extern void (*isr_stub_table[])(); extern void (*isr_stub_table[])();
using int_handler_t = void (*)(void *); using int_handler_t = void (*)(void *);
void attach_interrupt(unsigned num, int_handler_t handler, void *arg); void attach_interrupt(unsigned num, int_handler_t handler, void *arg);
#endif #endif

View File

@@ -27,4 +27,4 @@ static inline void io_wait(void) {
outb(0x80, 0); outb(0x80, 0);
} }
#endif//OS1_IO_H #endif //OS1_IO_H

View File

@@ -41,7 +41,7 @@ void ktask2() {
// Note: we assume the framebuffer model is RGB with 32-bit pixels. // Note: we assume the framebuffer model is RGB with 32-bit pixels.
for (size_t i = 0; i < 100; i++) { for (size_t i = 0; i < 100; i++) {
sleep_self(25000); sleep_self(25000);
uint32_t *fb_ptr = static_cast<uint32_t *>(framebuffer->address); uint32_t *fb_ptr = static_cast<uint32_t *>(framebuffer->address);
fb_ptr[i * (framebuffer->pitch / 4) + i + 100] = c ? 0 : 0xFFFFFF; fb_ptr[i * (framebuffer->pitch / 4) + i + 100] = c ? 0 : 0xFFFFFF;
} }
} }
@@ -60,7 +60,7 @@ void ktask() {
// Note: we assume the framebuffer model is RGB with 32-bit pixels. // Note: we assume the framebuffer model is RGB with 32-bit pixels.
for (size_t i = 0; i < 100; i++) { for (size_t i = 0; i < 100; i++) {
sleep_self(25000); sleep_self(25000);
uint32_t *fb_ptr = static_cast<uint32_t *>(framebuffer->address); uint32_t *fb_ptr = static_cast<uint32_t *>(framebuffer->address);
fb_ptr[i * (framebuffer->pitch / 4) + i] = c ? 0 : 0xFFFFFF; fb_ptr[i * (framebuffer->pitch / 4) + i] = c ? 0 : 0xFFFFFF;
} }
} }
@@ -94,16 +94,16 @@ void freeprinter() {
} }
void statprinter() { void statprinter() {
SkipList<uint64_t, std::pair<String, uint64_t>> last_times = getTaskTimePerPid(); SkipList<uint64_t, std::pair<String, uint64_t>> last_times = getTaskTimePerPid();
std::atomic<uint64_t> last_print_time = micros; std::atomic<uint64_t> last_print_time = micros;
while (1) { while (1) {
sleep_self(1000000); sleep_self(1000000);
uint64_t prev_print_time = last_print_time; uint64_t prev_print_time = last_print_time;
last_print_time = micros; last_print_time = micros;
SkipList<uint64_t, std::pair<String, uint64_t>> prev_times = std::move(last_times); SkipList<uint64_t, std::pair<String, uint64_t>> prev_times = std::move(last_times);
last_times = getTaskTimePerPid(); last_times = getTaskTimePerPid();
uint64_t slice = last_print_time - prev_print_time; uint64_t slice = last_print_time - prev_print_time;
if (slice == 0) continue; if (slice == 0) continue;
for (const auto &t: prev_times) { for (const auto &t: prev_times) {
@@ -134,7 +134,7 @@ void statprinter() {
static Mutex testmutex; static Mutex testmutex;
void mtest1() { void mtest1() {
{ {
LockGuard l(testmutex); LockGuard l(testmutex);
GlobalTtyManager.all_tty_putstr("Locked1\n"); GlobalTtyManager.all_tty_putstr("Locked1\n");
@@ -165,8 +165,8 @@ void mtest3() {
} }
void stress() { void stress() {
static std::atomic<int> i = 0; static std::atomic<int> i = 0;
int curi = i++; int curi = i++;
if (curi > 1500) remove_self(); if (curi > 1500) remove_self();
sleep_self(100000 - curi * 10); sleep_self(100000 - curi * 10);
@@ -252,13 +252,13 @@ void dummy_task() {
extern void (*ctors_begin[])(); extern void (*ctors_begin[])();
extern void (*ctors_end[])(); extern void (*ctors_end[])();
void kmain() { void kmain() {
for (void (**ctor)() = ctors_begin; ctor < ctors_end; ctor++) for (void (**ctor)() = ctors_begin; ctor < ctors_end; ctor++)
(*ctor)(); (*ctor)();
init_timer(); init_timer();
srand(micros);// NOLINT srand(micros); // NOLINT
new_ktask(ktask_main, "ktask_main"); new_ktask(ktask_main, "ktask_main");
new_ktask(dummy_task, "dummy"); new_ktask(dummy_task, "dummy");

View File

@@ -11,15 +11,15 @@
#include "mutex.hpp" #include "mutex.hpp"
#include "string.h" #include "string.h"
struct HeapEntry *KERN_HeapBegin; struct HeapEntry *KERN_HeapBegin;
uintptr_t KERN_HeapEnd;// Past the end uintptr_t KERN_HeapEnd; // Past the end
static bool initialized = false; static bool initialized = false;
std::atomic<uint64_t> allocated = 0; std::atomic<uint64_t> allocated = 0;
std::atomic<uint64_t> used = 0; std::atomic<uint64_t> used = 0;
uint64_t get_heap_allocated() { uint64_t get_heap_allocated() {
return allocated; return allocated;
} }
uint64_t get_heap_used() { uint64_t get_heap_used() {
@@ -28,17 +28,17 @@ uint64_t get_heap_used() {
static Mutex kmem_lock; static Mutex kmem_lock;
void init_kern_heap() { void init_kern_heap() {
KERN_HeapBegin = static_cast<HeapEntry *>(get4k()); KERN_HeapBegin = static_cast<HeapEntry *>(get4k());
allocated.fetch_add(PAGE_SIZE); allocated.fetch_add(PAGE_SIZE);
KERN_HeapBegin->magic = KERN_HeapMagicFree; KERN_HeapBegin->magic = KERN_HeapMagicFree;
KERN_HeapBegin->len = PAGE_SIZE - (sizeof(struct HeapEntry)); KERN_HeapBegin->len = PAGE_SIZE - (sizeof(struct HeapEntry));
KERN_HeapBegin->next = NULL; KERN_HeapBegin->next = NULL;
KERN_HeapBegin->prev = NULL; KERN_HeapBegin->prev = NULL;
KERN_AddressSpace->map((void *) KERN_HeapVirtBegin, (void *) HHDM_V2P(KERN_HeapBegin), PAGE_RW); KERN_AddressSpace->map((void *) KERN_HeapVirtBegin, (void *) HHDM_V2P(KERN_HeapBegin), PAGE_RW);
KERN_HeapBegin = (struct HeapEntry *) KERN_HeapVirtBegin; KERN_HeapBegin = (struct HeapEntry *) KERN_HeapVirtBegin;
KERN_HeapEnd = (KERN_HeapVirtBegin + PAGE_SIZE); KERN_HeapEnd = (KERN_HeapVirtBegin + PAGE_SIZE);
initialized = true; initialized = true;
} }
static void extend_heap(size_t n_pages) { static void extend_heap(size_t n_pages) {
@@ -67,10 +67,10 @@ struct HeapEntry *split_entry(struct HeapEntry *what, size_t n) {
assert(what->len <= allocated); assert(what->len <= allocated);
new_entry->magic = KERN_HeapMagicFree; new_entry->magic = KERN_HeapMagicFree;
new_entry->next = what->next; new_entry->next = what->next;
new_entry->prev = what; new_entry->prev = what;
new_entry->len = what->len - n - sizeof(struct HeapEntry); new_entry->len = what->len - n - sizeof(struct HeapEntry);
what->len = n; what->len = n;
if (new_entry->next) if (new_entry->next)
new_entry->next->prev = new_entry; new_entry->next->prev = new_entry;
@@ -96,7 +96,7 @@ void *kmalloc(size_t n) {
struct HeapEntry *res = NULL; struct HeapEntry *res = NULL;
{ {
LockGuard l(kmem_lock); LockGuard l(kmem_lock);
struct HeapEntry *entry = KERN_HeapBegin; struct HeapEntry *entry = KERN_HeapBegin;
assert2(entry->magic == KERN_HeapMagicFree, "Bad heap!"); assert2(entry->magic == KERN_HeapMagicFree, "Bad heap!");
@@ -119,28 +119,28 @@ void *kmalloc(size_t n) {
entry->next->prev = prev; entry->next->prev = prev;
} else { } else {
if (entry->next) { if (entry->next) {
KERN_HeapBegin = entry->next; KERN_HeapBegin = entry->next;
entry->next->prev = NULL; entry->next->prev = NULL;
} else { } else {
KERN_HeapBegin = (struct HeapEntry *) KERN_HeapEnd; KERN_HeapBegin = (struct HeapEntry *) KERN_HeapEnd;
extend_heap(1); extend_heap(1);
KERN_HeapBegin->next = NULL; KERN_HeapBegin->next = NULL;
KERN_HeapBegin->prev = NULL; KERN_HeapBegin->prev = NULL;
KERN_HeapBegin->magic = KERN_HeapMagicFree; KERN_HeapBegin->magic = KERN_HeapMagicFree;
KERN_HeapBegin->len = PAGE_SIZE - (sizeof(struct HeapEntry)); KERN_HeapBegin->len = PAGE_SIZE - (sizeof(struct HeapEntry));
} }
} }
break; break;
} }
if (entry->len > n + sizeof(struct HeapEntry)) { if (entry->len > n + sizeof(struct HeapEntry)) {
res = entry; res = entry;
struct HeapEntry *new_split_entry = split_entry(res, n); struct HeapEntry *new_split_entry = split_entry(res, n);
if (prev) { if (prev) {
prev->next = new_split_entry; prev->next = new_split_entry;
new_split_entry->prev = prev; new_split_entry->prev = prev;
} else { } else {
KERN_HeapBegin = new_split_entry; KERN_HeapBegin = new_split_entry;
new_split_entry->prev = NULL; new_split_entry->prev = NULL;
} }
if (new_split_entry->prev) if (new_split_entry->prev)
@@ -148,7 +148,7 @@ void *kmalloc(size_t n) {
break; break;
} }
prev = entry; prev = entry;
entry = entry->next; entry = entry->next;
} while (entry); } while (entry);
@@ -158,24 +158,24 @@ void *kmalloc(size_t n) {
assert2(entry->magic == KERN_HeapMagicFree, "Expected last tried entry to be free"); assert2(entry->magic == KERN_HeapMagicFree, "Expected last tried entry to be free");
assert2(entry->next == NULL, "Expected last tried entry to be the last"); assert2(entry->next == NULL, "Expected last tried entry to be the last");
size_t data_needed = n + (2 * sizeof(struct HeapEntry)); size_t data_needed = n + (2 * sizeof(struct HeapEntry));
size_t pages_needed = ((data_needed & 0xFFF) == 0) size_t pages_needed = ((data_needed & 0xFFF) == 0)
? data_needed >> 12 ? data_needed >> 12
: ((data_needed & (~0xFFF)) + 0x1000) >> 12; : ((data_needed & (~0xFFF)) + 0x1000) >> 12;
struct HeapEntry *new_entry = (struct HeapEntry *) KERN_HeapEnd; struct HeapEntry *new_entry = (struct HeapEntry *) KERN_HeapEnd;
extend_heap(pages_needed); extend_heap(pages_needed);
new_entry->next = NULL; new_entry->next = NULL;
new_entry->prev = entry; new_entry->prev = entry;
new_entry->magic = KERN_HeapMagicFree; new_entry->magic = KERN_HeapMagicFree;
new_entry->len = (pages_needed * PAGE_SIZE) - (sizeof(struct HeapEntry)); new_entry->len = (pages_needed * PAGE_SIZE) - (sizeof(struct HeapEntry));
assert2(new_entry->len >= n, "Expected allocated heap entry to fit what we wanted"); assert2(new_entry->len >= n, "Expected allocated heap entry to fit what we wanted");
res = new_entry; res = new_entry;
if (new_entry->len > n) { if (new_entry->len > n) {
struct HeapEntry *new_split_entry = split_entry(res, n); struct HeapEntry *new_split_entry = split_entry(res, n);
entry->next = new_split_entry; entry->next = new_split_entry;
new_split_entry->prev = entry; new_split_entry->prev = entry;
if (new_split_entry->prev) if (new_split_entry->prev)
assert(new_split_entry->prev->magic == KERN_HeapMagicFree); assert(new_split_entry->prev->magic == KERN_HeapMagicFree);
} }
@@ -188,8 +188,8 @@ void *kmalloc(size_t n) {
// if (res->next) res->next->prev = res->prev; // if (res->next) res->next->prev = res->prev;
// if (res->prev) res->prev->next = res->next; // if (res->prev) res->prev->next = res->next;
res->next = NULL; res->next = NULL;
res->prev = NULL; res->prev = NULL;
res->magic = KERN_HeapMagicTaken; res->magic = KERN_HeapMagicTaken;
} }
assert((((uintptr_t) res->data) & 0xFULL) == 0); assert((((uintptr_t) res->data) & 0xFULL) == 0);
@@ -211,21 +211,21 @@ static void try_merge_fwd(struct HeapEntry *entry) {
if (nextEntry == entry->next) { if (nextEntry == entry->next) {
nextEntry->next->prev = entry; nextEntry->next->prev = entry;
entry->next = nextEntry->next; entry->next = nextEntry->next;
} else { } else {
assert(nextEntry->prev && nextEntry->prev->magic == KERN_HeapMagicFree); assert(nextEntry->prev && nextEntry->prev->magic == KERN_HeapMagicFree);
struct HeapEntry *victimR = nextEntry->next; struct HeapEntry *victimR = nextEntry->next;
if (victimR) { if (victimR) {
assert(victimR->magic == KERN_HeapMagicFree); assert(victimR->magic == KERN_HeapMagicFree);
victimR->prev = nextEntry->prev; victimR->prev = nextEntry->prev;
nextEntry->prev->next = victimR; nextEntry->prev->next = victimR;
} else { } else {
nextEntry->prev->next = NULL; nextEntry->prev->next = NULL;
} }
} }
entry->len = entry->len + sizeof(struct HeapEntry) + nextEntry->len; entry->len = entry->len + sizeof(struct HeapEntry) + nextEntry->len;
nextEntry = (struct HeapEntry *) ((uint64_t) entry + sizeof(struct HeapEntry) + entry->len); nextEntry = (struct HeapEntry *) ((uint64_t) entry + sizeof(struct HeapEntry) + entry->len);
} }
} }
@@ -248,18 +248,18 @@ static struct HeapEntry *try_shrink_heap(struct HeapEntry *entry) {
// But also check if it's enough... // But also check if it's enough...
if (diff <= sizeof(struct HeapEntry)) diff += 0x1000ULL; if (diff <= sizeof(struct HeapEntry)) diff += 0x1000ULL;
entry = split_entry(entry, diff - sizeof(struct HeapEntry)); entry = split_entry(entry, diff - sizeof(struct HeapEntry));
ret = entry->prev; ret = entry->prev;
ret->next = entry->next; ret->next = entry->next;
if (entry->next) if (entry->next)
entry->next->prev = ret; entry->next->prev = ret;
} else { } else {
ret = entry->next; ret = entry->next;
ret->prev = NULL; ret->prev = NULL;
} }
assert(((uint64_t) entry & 0xFFF) == 0); assert(((uint64_t) entry & 0xFFF) == 0);
KERN_HeapEnd = (uintptr_t) entry; KERN_HeapEnd = (uintptr_t) entry;
uint64_t totallen = entry->len + sizeof(struct HeapEntry); uint64_t totallen = entry->len + sizeof(struct HeapEntry);
assert(((uint64_t) totallen & 0xFFF) == 0); assert(((uint64_t) totallen & 0xFFF) == 0);
uint64_t total_pages = totallen / PAGE_SIZE; uint64_t total_pages = totallen / PAGE_SIZE;
@@ -276,7 +276,7 @@ static struct HeapEntry *try_shrink_heap(struct HeapEntry *entry) {
void kfree(void *addr) { void kfree(void *addr) {
assert(initialized); assert(initialized);
LockGuard l(kmem_lock); LockGuard l(kmem_lock);
struct HeapEntry *freed = (struct HeapEntry *) (addr - (sizeof(struct HeapEntry))); struct HeapEntry *freed = (struct HeapEntry *) (addr - (sizeof(struct HeapEntry)));
used.fetch_sub(freed->len); used.fetch_sub(freed->len);
@@ -288,10 +288,10 @@ void kfree(void *addr) {
assert2(entry->magic == KERN_HeapMagicFree, "Bad free!"); assert2(entry->magic == KERN_HeapMagicFree, "Bad free!");
assert2(entry->prev == NULL, "Bad free!"); assert2(entry->prev == NULL, "Bad free!");
freed->next = entry; freed->next = entry;
entry->prev = freed; entry->prev = freed;
KERN_HeapBegin = freed; KERN_HeapBegin = freed;
freed->magic = KERN_HeapMagicFree; freed->magic = KERN_HeapMagicFree;
try_merge_fwd(freed); try_merge_fwd(freed);
assert2(freed->prev == NULL, "Bad free!"); assert2(freed->prev == NULL, "Bad free!");

View File

@@ -4,28 +4,28 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#define KERN_HeapVirtBegin (0xffffc00000000000ULL) #define KERN_HeapVirtBegin (0xffffc00000000000ULL)
#define KERN_HeapMagicFree 0xDEDE #define KERN_HeapMagicFree 0xDEDE
#define KERN_HeapMagicTaken 0xADAD #define KERN_HeapMagicTaken 0xADAD
void init_kern_heap(); void init_kern_heap();
struct HeapEntry { struct HeapEntry {
uint_fast16_t magic; uint_fast16_t magic;
struct HeapEntry *next; struct HeapEntry *next;
struct HeapEntry *prev; struct HeapEntry *prev;
uint64_t len; uint64_t len;
char data[] __attribute__((aligned(16))); char data[] __attribute__((aligned(16)));
} __attribute__((packed, aligned(32))); } __attribute__((packed, aligned(32)));
extern struct HeapEntry *KERN_HeapBegin; extern struct HeapEntry *KERN_HeapBegin;
extern uintptr_t KERN_HeapEnd;// Past the end extern uintptr_t KERN_HeapEnd; // Past the end
void *kmalloc(size_t n); void *kmalloc(size_t n);
void kfree(void *addr); void kfree(void *addr);
void *krealloc(void *addr, size_t newsize); void *krealloc(void *addr, size_t newsize);
uint64_t get_heap_allocated(); uint64_t get_heap_allocated();
uint64_t get_heap_used(); uint64_t get_heap_used();
#endif #endif

View File

@@ -26,22 +26,22 @@ extern "C" {
/* Misc */ /* Misc */
#ifdef LIMINE_NO_POINTERS #ifdef LIMINE_NO_POINTERS
# define LIMINE_PTR(TYPE) uint64_t #define LIMINE_PTR(TYPE) uint64_t
#else #else
# define LIMINE_PTR(TYPE) TYPE #define LIMINE_PTR(TYPE) TYPE
#endif #endif
#ifdef __GNUC__ #ifdef __GNUC__
# define LIMINE_DEPRECATED __attribute__((__deprecated__)) #define LIMINE_DEPRECATED __attribute__((__deprecated__))
# define LIMINE_DEPRECATED_IGNORE_START \ #define LIMINE_DEPRECATED_IGNORE_START \
_Pragma("GCC diagnostic push") \ _Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
# define LIMINE_DEPRECATED_IGNORE_END \ #define LIMINE_DEPRECATED_IGNORE_END \
_Pragma("GCC diagnostic pop") _Pragma("GCC diagnostic pop")
#else #else
# define LIMINE_DEPRECATED #define LIMINE_DEPRECATED
# define LIMINE_DEPRECATED_IGNORE_START #define LIMINE_DEPRECATED_IGNORE_START
# define LIMINE_DEPRECATED_IGNORE_END #define LIMINE_DEPRECATED_IGNORE_END
#endif #endif
#define LIMINE_COMMON_MAGIC 0xc7b1dd30df4c8b88, 0x0a82e883a194f07b #define LIMINE_COMMON_MAGIC 0xc7b1dd30df4c8b88, 0x0a82e883a194f07b
@@ -50,25 +50,28 @@ struct limine_uuid {
uint32_t a; uint32_t a;
uint16_t b; uint16_t b;
uint16_t c; uint16_t c;
uint8_t d[8]; uint8_t d[8];
}; };
#define LIMINE_MEDIA_TYPE_GENERIC 0 #define LIMINE_MEDIA_TYPE_GENERIC 0
#define LIMINE_MEDIA_TYPE_OPTICAL 1 #define LIMINE_MEDIA_TYPE_OPTICAL 1
#define LIMINE_MEDIA_TYPE_TFTP 2 #define LIMINE_MEDIA_TYPE_TFTP 2
struct limine_file { struct limine_file {
uint64_t revision; uint64_t revision;
LIMINE_PTR(void *) address; LIMINE_PTR(void *)
address;
uint64_t size; uint64_t size;
LIMINE_PTR(char *) path; LIMINE_PTR(char *)
LIMINE_PTR(char *) cmdline; path;
uint32_t media_type; LIMINE_PTR(char *)
uint32_t unused; cmdline;
uint32_t tftp_ip; uint32_t media_type;
uint32_t tftp_port; uint32_t unused;
uint32_t partition_index; uint32_t tftp_ip;
uint32_t mbr_disk_id; uint32_t tftp_port;
uint32_t partition_index;
uint32_t mbr_disk_id;
struct limine_uuid gpt_disk_uuid; struct limine_uuid gpt_disk_uuid;
struct limine_uuid gpt_part_uuid; struct limine_uuid gpt_part_uuid;
struct limine_uuid part_uuid; struct limine_uuid part_uuid;
@@ -76,23 +79,28 @@ struct limine_file {
/* Boot info */ /* Boot info */
#define LIMINE_BOOTLOADER_INFO_REQUEST { LIMINE_COMMON_MAGIC, 0xf55038d8e2a1202f, 0x279426fcf5f59740 } #define LIMINE_BOOTLOADER_INFO_REQUEST \
{ LIMINE_COMMON_MAGIC, 0xf55038d8e2a1202f, 0x279426fcf5f59740 }
struct limine_bootloader_info_response { struct limine_bootloader_info_response {
uint64_t revision; uint64_t revision;
LIMINE_PTR(char *) name; LIMINE_PTR(char *)
LIMINE_PTR(char *) version; name;
LIMINE_PTR(char *)
version;
}; };
struct limine_bootloader_info_request { struct limine_bootloader_info_request {
uint64_t id[4]; uint64_t id[4];
uint64_t revision; uint64_t revision;
LIMINE_PTR(struct limine_bootloader_info_response *) response; LIMINE_PTR(struct limine_bootloader_info_response *)
response;
}; };
/* Stack size */ /* Stack size */
#define LIMINE_STACK_SIZE_REQUEST { LIMINE_COMMON_MAGIC, 0x224ef0460a8e8926, 0xe1cb0fc25f46ea3d } #define LIMINE_STACK_SIZE_REQUEST \
{ LIMINE_COMMON_MAGIC, 0x224ef0460a8e8926, 0xe1cb0fc25f46ea3d }
struct limine_stack_size_response { struct limine_stack_size_response {
uint64_t revision; uint64_t revision;
@@ -101,13 +109,15 @@ struct limine_stack_size_response {
struct limine_stack_size_request { struct limine_stack_size_request {
uint64_t id[4]; uint64_t id[4];
uint64_t revision; uint64_t revision;
LIMINE_PTR(struct limine_stack_size_response *) response; LIMINE_PTR(struct limine_stack_size_response *)
response;
uint64_t stack_size; uint64_t stack_size;
}; };
/* HHDM */ /* HHDM */
#define LIMINE_HHDM_REQUEST { LIMINE_COMMON_MAGIC, 0x48dcf1cb8ad2b852, 0x63984e959a98244b } #define LIMINE_HHDM_REQUEST \
{ LIMINE_COMMON_MAGIC, 0x48dcf1cb8ad2b852, 0x63984e959a98244b }
struct limine_hhdm_response { struct limine_hhdm_response {
uint64_t revision; uint64_t revision;
@@ -117,12 +127,14 @@ struct limine_hhdm_response {
struct limine_hhdm_request { struct limine_hhdm_request {
uint64_t id[4]; uint64_t id[4];
uint64_t revision; uint64_t revision;
LIMINE_PTR(struct limine_hhdm_response *) response; LIMINE_PTR(struct limine_hhdm_response *)
response;
}; };
/* Framebuffer */ /* Framebuffer */
#define LIMINE_FRAMEBUFFER_REQUEST { LIMINE_COMMON_MAGIC, 0x9d5827dcd881dd75, 0xa3148604f6fab11b } #define LIMINE_FRAMEBUFFER_REQUEST \
{ LIMINE_COMMON_MAGIC, 0x9d5827dcd881dd75, 0xa3148604f6fab11b }
#define LIMINE_FRAMEBUFFER_RGB 1 #define LIMINE_FRAMEBUFFER_RGB 1
@@ -131,128 +143,140 @@ struct limine_video_mode {
uint64_t width; uint64_t width;
uint64_t height; uint64_t height;
uint16_t bpp; uint16_t bpp;
uint8_t memory_model; uint8_t memory_model;
uint8_t red_mask_size; uint8_t red_mask_size;
uint8_t red_mask_shift; uint8_t red_mask_shift;
uint8_t green_mask_size; uint8_t green_mask_size;
uint8_t green_mask_shift; uint8_t green_mask_shift;
uint8_t blue_mask_size; uint8_t blue_mask_size;
uint8_t blue_mask_shift; uint8_t blue_mask_shift;
}; };
struct limine_framebuffer { struct limine_framebuffer {
LIMINE_PTR(void *) address; LIMINE_PTR(void *)
address;
uint64_t width; uint64_t width;
uint64_t height; uint64_t height;
uint64_t pitch; uint64_t pitch;
uint16_t bpp; uint16_t bpp;
uint8_t memory_model; uint8_t memory_model;
uint8_t red_mask_size; uint8_t red_mask_size;
uint8_t red_mask_shift; uint8_t red_mask_shift;
uint8_t green_mask_size; uint8_t green_mask_size;
uint8_t green_mask_shift; uint8_t green_mask_shift;
uint8_t blue_mask_size; uint8_t blue_mask_size;
uint8_t blue_mask_shift; uint8_t blue_mask_shift;
uint8_t unused[7]; uint8_t unused[7];
uint64_t edid_size; uint64_t edid_size;
LIMINE_PTR(void *) edid; LIMINE_PTR(void *)
edid;
/* Response revision 1 */ /* Response revision 1 */
uint64_t mode_count; uint64_t mode_count;
LIMINE_PTR(struct limine_video_mode **) modes; LIMINE_PTR(struct limine_video_mode **)
modes;
}; };
struct limine_framebuffer_response { struct limine_framebuffer_response {
uint64_t revision; uint64_t revision;
uint64_t framebuffer_count; uint64_t framebuffer_count;
LIMINE_PTR(struct limine_framebuffer **) framebuffers; LIMINE_PTR(struct limine_framebuffer **)
framebuffers;
}; };
struct limine_framebuffer_request { struct limine_framebuffer_request {
uint64_t id[4]; uint64_t id[4];
uint64_t revision; uint64_t revision;
LIMINE_PTR(struct limine_framebuffer_response *) response; LIMINE_PTR(struct limine_framebuffer_response *)
response;
}; };
/* Terminal */ /* Terminal */
#define LIMINE_TERMINAL_REQUEST { LIMINE_COMMON_MAGIC, 0xc8ac59310c2b0844, 0xa68d0c7265d38878 } #define LIMINE_TERMINAL_REQUEST \
{ LIMINE_COMMON_MAGIC, 0xc8ac59310c2b0844, 0xa68d0c7265d38878 }
#define LIMINE_TERMINAL_CB_DEC 10 #define LIMINE_TERMINAL_CB_DEC 10
#define LIMINE_TERMINAL_CB_BELL 20 #define LIMINE_TERMINAL_CB_BELL 20
#define LIMINE_TERMINAL_CB_PRIVATE_ID 30 #define LIMINE_TERMINAL_CB_PRIVATE_ID 30
#define LIMINE_TERMINAL_CB_STATUS_REPORT 40 #define LIMINE_TERMINAL_CB_STATUS_REPORT 40
#define LIMINE_TERMINAL_CB_POS_REPORT 50 #define LIMINE_TERMINAL_CB_POS_REPORT 50
#define LIMINE_TERMINAL_CB_KBD_LEDS 60 #define LIMINE_TERMINAL_CB_KBD_LEDS 60
#define LIMINE_TERMINAL_CB_MODE 70 #define LIMINE_TERMINAL_CB_MODE 70
#define LIMINE_TERMINAL_CB_LINUX 80 #define LIMINE_TERMINAL_CB_LINUX 80
#define LIMINE_TERMINAL_CTX_SIZE ((uint64_t)(-1)) #define LIMINE_TERMINAL_CTX_SIZE ((uint64_t) (-1))
#define LIMINE_TERMINAL_CTX_SAVE ((uint64_t)(-2)) #define LIMINE_TERMINAL_CTX_SAVE ((uint64_t) (-2))
#define LIMINE_TERMINAL_CTX_RESTORE ((uint64_t)(-3)) #define LIMINE_TERMINAL_CTX_RESTORE ((uint64_t) (-3))
#define LIMINE_TERMINAL_FULL_REFRESH ((uint64_t)(-4)) #define LIMINE_TERMINAL_FULL_REFRESH ((uint64_t) (-4))
/* Response revision 1 */ /* Response revision 1 */
#define LIMINE_TERMINAL_OOB_OUTPUT_GET ((uint64_t)(-10)) #define LIMINE_TERMINAL_OOB_OUTPUT_GET ((uint64_t) (-10))
#define LIMINE_TERMINAL_OOB_OUTPUT_SET ((uint64_t)(-11)) #define LIMINE_TERMINAL_OOB_OUTPUT_SET ((uint64_t) (-11))
#define LIMINE_TERMINAL_OOB_OUTPUT_OCRNL (1 << 0) #define LIMINE_TERMINAL_OOB_OUTPUT_OCRNL (1 << 0)
#define LIMINE_TERMINAL_OOB_OUTPUT_OFDEL (1 << 1) #define LIMINE_TERMINAL_OOB_OUTPUT_OFDEL (1 << 1)
#define LIMINE_TERMINAL_OOB_OUTPUT_OFILL (1 << 2) #define LIMINE_TERMINAL_OOB_OUTPUT_OFILL (1 << 2)
#define LIMINE_TERMINAL_OOB_OUTPUT_OLCUC (1 << 3) #define LIMINE_TERMINAL_OOB_OUTPUT_OLCUC (1 << 3)
#define LIMINE_TERMINAL_OOB_OUTPUT_ONLCR (1 << 4) #define LIMINE_TERMINAL_OOB_OUTPUT_ONLCR (1 << 4)
#define LIMINE_TERMINAL_OOB_OUTPUT_ONLRET (1 << 5) #define LIMINE_TERMINAL_OOB_OUTPUT_ONLRET (1 << 5)
#define LIMINE_TERMINAL_OOB_OUTPUT_ONOCR (1 << 6) #define LIMINE_TERMINAL_OOB_OUTPUT_ONOCR (1 << 6)
#define LIMINE_TERMINAL_OOB_OUTPUT_OPOST (1 << 7) #define LIMINE_TERMINAL_OOB_OUTPUT_OPOST (1 << 7)
LIMINE_DEPRECATED_IGNORE_START LIMINE_DEPRECATED_IGNORE_START
struct LIMINE_DEPRECATED limine_terminal; struct LIMINE_DEPRECATED limine_terminal;
typedef void (*limine_terminal_write)(struct limine_terminal *, const char *, uint64_t); typedef void (*limine_terminal_write)(struct limine_terminal *, const char *, uint64_t);
typedef void (*limine_terminal_callback)(struct limine_terminal *, uint64_t, uint64_t, uint64_t, uint64_t); typedef void (*limine_terminal_callback)(struct limine_terminal *, uint64_t, uint64_t, uint64_t, uint64_t);
struct LIMINE_DEPRECATED limine_terminal { struct LIMINE_DEPRECATED limine_terminal {
uint64_t columns; uint64_t columns;
uint64_t rows; uint64_t rows;
LIMINE_PTR(struct limine_framebuffer *) framebuffer; LIMINE_PTR(struct limine_framebuffer *)
framebuffer;
}; };
struct LIMINE_DEPRECATED limine_terminal_response { struct LIMINE_DEPRECATED limine_terminal_response {
uint64_t revision; uint64_t revision;
uint64_t terminal_count; uint64_t terminal_count;
LIMINE_PTR(struct limine_terminal **) terminals; LIMINE_PTR(struct limine_terminal **)
LIMINE_PTR(limine_terminal_write) write; terminals;
LIMINE_PTR(limine_terminal_write)
write;
}; };
struct LIMINE_DEPRECATED limine_terminal_request { struct LIMINE_DEPRECATED limine_terminal_request {
uint64_t id[4]; uint64_t id[4];
uint64_t revision; uint64_t revision;
LIMINE_PTR(struct limine_terminal_response *) response; LIMINE_PTR(struct limine_terminal_response *)
LIMINE_PTR(limine_terminal_callback) callback; response;
LIMINE_PTR(limine_terminal_callback)
callback;
}; };
LIMINE_DEPRECATED_IGNORE_END LIMINE_DEPRECATED_IGNORE_END
/* Paging mode */ /* Paging mode */
#define LIMINE_PAGING_MODE_REQUEST { LIMINE_COMMON_MAGIC, 0x95c1a0edab0944cb, 0xa4e5cb3842f7488a } #define LIMINE_PAGING_MODE_REQUEST \
{ LIMINE_COMMON_MAGIC, 0x95c1a0edab0944cb, 0xa4e5cb3842f7488a }
#if defined (__x86_64__) || defined (__i386__) #if defined(__x86_64__) || defined(__i386__)
#define LIMINE_PAGING_MODE_X86_64_4LVL 0 #define LIMINE_PAGING_MODE_X86_64_4LVL 0
#define LIMINE_PAGING_MODE_X86_64_5LVL 1 #define LIMINE_PAGING_MODE_X86_64_5LVL 1
#define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_X86_64_5LVL #define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_X86_64_5LVL
#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_X86_64_4LVL #define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_X86_64_4LVL
#elif defined (__aarch64__) #elif defined(__aarch64__)
#define LIMINE_PAGING_MODE_AARCH64_4LVL 0 #define LIMINE_PAGING_MODE_AARCH64_4LVL 0
#define LIMINE_PAGING_MODE_AARCH64_5LVL 1 #define LIMINE_PAGING_MODE_AARCH64_5LVL 1
#define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_AARCH64_5LVL #define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_AARCH64_5LVL
#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_AARCH64_4LVL #define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_AARCH64_4LVL
#elif defined (__riscv) && (__riscv_xlen == 64) #elif defined(__riscv) && (__riscv_xlen == 64)
#define LIMINE_PAGING_MODE_RISCV_SV39 0 #define LIMINE_PAGING_MODE_RISCV_SV39 0
#define LIMINE_PAGING_MODE_RISCV_SV48 1 #define LIMINE_PAGING_MODE_RISCV_SV48 1
#define LIMINE_PAGING_MODE_RISCV_SV57 2 #define LIMINE_PAGING_MODE_RISCV_SV57 2
#define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_RISCV_SV57 #define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_RISCV_SV57
#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_RISCV_SV48 #define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_RISCV_SV48
#else #else
#error Unknown architecture #error Unknown architecture
#endif #endif
@@ -266,14 +290,16 @@ struct limine_paging_mode_response {
struct limine_paging_mode_request { struct limine_paging_mode_request {
uint64_t id[4]; uint64_t id[4];
uint64_t revision; uint64_t revision;
LIMINE_PTR(struct limine_paging_mode_response *) response; LIMINE_PTR(struct limine_paging_mode_response *)
response;
uint64_t mode; uint64_t mode;
uint64_t flags; uint64_t flags;
}; };
/* 5-level paging */ /* 5-level paging */
#define LIMINE_5_LEVEL_PAGING_REQUEST { LIMINE_COMMON_MAGIC, 0x94469551da9b3192, 0xebe5e86db7382888 } #define LIMINE_5_LEVEL_PAGING_REQUEST \
{ LIMINE_COMMON_MAGIC, 0x94469551da9b3192, 0xebe5e86db7382888 }
LIMINE_DEPRECATED_IGNORE_START LIMINE_DEPRECATED_IGNORE_START
@@ -284,20 +310,22 @@ struct LIMINE_DEPRECATED limine_5_level_paging_response {
struct LIMINE_DEPRECATED limine_5_level_paging_request { struct LIMINE_DEPRECATED limine_5_level_paging_request {
uint64_t id[4]; uint64_t id[4];
uint64_t revision; uint64_t revision;
LIMINE_PTR(struct limine_5_level_paging_response *) response; LIMINE_PTR(struct limine_5_level_paging_response *)
response;
}; };
LIMINE_DEPRECATED_IGNORE_END LIMINE_DEPRECATED_IGNORE_END
/* SMP */ /* SMP */
#define LIMINE_SMP_REQUEST { LIMINE_COMMON_MAGIC, 0x95a67b819a1b857e, 0xa0b61b723b6a73e0 } #define LIMINE_SMP_REQUEST \
{ LIMINE_COMMON_MAGIC, 0x95a67b819a1b857e, 0xa0b61b723b6a73e0 }
struct limine_smp_info; struct limine_smp_info;
typedef void (*limine_goto_address)(struct limine_smp_info *); typedef void (*limine_goto_address)(struct limine_smp_info *);
#if defined (__x86_64__) || defined (__i386__) #if defined(__x86_64__) || defined(__i386__)
#define LIMINE_SMP_X2APIC (1 << 0) #define LIMINE_SMP_X2APIC (1 << 0)
@@ -305,7 +333,8 @@ struct limine_smp_info {
uint32_t processor_id; uint32_t processor_id;
uint32_t lapic_id; uint32_t lapic_id;
uint64_t reserved; uint64_t reserved;
LIMINE_PTR(limine_goto_address) goto_address; LIMINE_PTR(limine_goto_address)
goto_address;
uint64_t extra_argument; uint64_t extra_argument;
}; };
@@ -314,17 +343,19 @@ struct limine_smp_response {
uint32_t flags; uint32_t flags;
uint32_t bsp_lapic_id; uint32_t bsp_lapic_id;
uint64_t cpu_count; uint64_t cpu_count;
LIMINE_PTR(struct limine_smp_info **) cpus; LIMINE_PTR(struct limine_smp_info **)
cpus;
}; };
#elif defined (__aarch64__) #elif defined(__aarch64__)
struct limine_smp_info { struct limine_smp_info {
uint32_t processor_id; uint32_t processor_id;
uint32_t gic_iface_no; uint32_t gic_iface_no;
uint64_t mpidr; uint64_t mpidr;
uint64_t reserved; uint64_t reserved;
LIMINE_PTR(limine_goto_address) goto_address; LIMINE_PTR(limine_goto_address)
goto_address;
uint64_t extra_argument; uint64_t extra_argument;
}; };
@@ -333,16 +364,18 @@ struct limine_smp_response {
uint32_t flags; uint32_t flags;
uint64_t bsp_mpidr; uint64_t bsp_mpidr;
uint64_t cpu_count; uint64_t cpu_count;
LIMINE_PTR(struct limine_smp_info **) cpus; LIMINE_PTR(struct limine_smp_info **)
cpus;
}; };
#elif defined (__riscv) && (__riscv_xlen == 64) #elif defined(__riscv) && (__riscv_xlen == 64)
struct limine_smp_info { struct limine_smp_info {
uint32_t processor_id; uint32_t processor_id;
uint64_t hartid; uint64_t hartid;
uint64_t reserved; uint64_t reserved;
LIMINE_PTR(limine_goto_address) goto_address; LIMINE_PTR(limine_goto_address)
goto_address;
uint64_t extra_argument; uint64_t extra_argument;
}; };
@@ -351,7 +384,8 @@ struct limine_smp_response {
uint32_t flags; uint32_t flags;
uint64_t bsp_hartid; uint64_t bsp_hartid;
uint64_t cpu_count; uint64_t cpu_count;
LIMINE_PTR(struct limine_smp_info **) cpus; LIMINE_PTR(struct limine_smp_info **)
cpus;
}; };
#else #else
@@ -361,13 +395,15 @@ struct limine_smp_response {
struct limine_smp_request { struct limine_smp_request {
uint64_t id[4]; uint64_t id[4];
uint64_t revision; uint64_t revision;
LIMINE_PTR(struct limine_smp_response *) response; LIMINE_PTR(struct limine_smp_response *)
response;
uint64_t flags; uint64_t flags;
}; };
/* Memory map */ /* Memory map */
#define LIMINE_MEMMAP_REQUEST { LIMINE_COMMON_MAGIC, 0x67cf3d9d378a806f, 0xe304acdfc50c3c62 } #define LIMINE_MEMMAP_REQUEST \
{ LIMINE_COMMON_MAGIC, 0x67cf3d9d378a806f, 0xe304acdfc50c3c62 }
#define LIMINE_MEMMAP_USABLE 0 #define LIMINE_MEMMAP_USABLE 0
#define LIMINE_MEMMAP_RESERVED 1 #define LIMINE_MEMMAP_RESERVED 1
@@ -387,18 +423,21 @@ struct limine_memmap_entry {
struct limine_memmap_response { struct limine_memmap_response {
uint64_t revision; uint64_t revision;
uint64_t entry_count; uint64_t entry_count;
LIMINE_PTR(struct limine_memmap_entry **) entries; LIMINE_PTR(struct limine_memmap_entry **)
entries;
}; };
struct limine_memmap_request { struct limine_memmap_request {
uint64_t id[4]; uint64_t id[4];
uint64_t revision; uint64_t revision;
LIMINE_PTR(struct limine_memmap_response *) response; LIMINE_PTR(struct limine_memmap_response *)
response;
}; };
/* Entry point */ /* Entry point */
#define LIMINE_ENTRY_POINT_REQUEST { LIMINE_COMMON_MAGIC, 0x13d86c035a1cd3e1, 0x2b0caa89d8f3026a } #define LIMINE_ENTRY_POINT_REQUEST \
{ LIMINE_COMMON_MAGIC, 0x13d86c035a1cd3e1, 0x2b0caa89d8f3026a }
typedef void (*limine_entry_point)(void); typedef void (*limine_entry_point)(void);
@@ -409,117 +448,141 @@ struct limine_entry_point_response {
struct limine_entry_point_request { struct limine_entry_point_request {
uint64_t id[4]; uint64_t id[4];
uint64_t revision; uint64_t revision;
LIMINE_PTR(struct limine_entry_point_response *) response; LIMINE_PTR(struct limine_entry_point_response *)
LIMINE_PTR(limine_entry_point) entry; response;
LIMINE_PTR(limine_entry_point)
entry;
}; };
/* Kernel File */ /* Kernel File */
#define LIMINE_KERNEL_FILE_REQUEST { LIMINE_COMMON_MAGIC, 0xad97e90e83f1ed67, 0x31eb5d1c5ff23b69 } #define LIMINE_KERNEL_FILE_REQUEST \
{ LIMINE_COMMON_MAGIC, 0xad97e90e83f1ed67, 0x31eb5d1c5ff23b69 }
struct limine_kernel_file_response { struct limine_kernel_file_response {
uint64_t revision; uint64_t revision;
LIMINE_PTR(struct limine_file *) kernel_file; LIMINE_PTR(struct limine_file *)
kernel_file;
}; };
struct limine_kernel_file_request { struct limine_kernel_file_request {
uint64_t id[4]; uint64_t id[4];
uint64_t revision; uint64_t revision;
LIMINE_PTR(struct limine_kernel_file_response *) response; LIMINE_PTR(struct limine_kernel_file_response *)
response;
}; };
/* Module */ /* Module */
#define LIMINE_MODULE_REQUEST { LIMINE_COMMON_MAGIC, 0x3e7e279702be32af, 0xca1c4f3bd1280cee } #define LIMINE_MODULE_REQUEST \
{ LIMINE_COMMON_MAGIC, 0x3e7e279702be32af, 0xca1c4f3bd1280cee }
#define LIMINE_INTERNAL_MODULE_REQUIRED (1 << 0) #define LIMINE_INTERNAL_MODULE_REQUIRED (1 << 0)
struct limine_internal_module { struct limine_internal_module {
LIMINE_PTR(const char *) path; LIMINE_PTR(const char *)
LIMINE_PTR(const char *) cmdline; path;
LIMINE_PTR(const char *)
cmdline;
uint64_t flags; uint64_t flags;
}; };
struct limine_module_response { struct limine_module_response {
uint64_t revision; uint64_t revision;
uint64_t module_count; uint64_t module_count;
LIMINE_PTR(struct limine_file **) modules; LIMINE_PTR(struct limine_file **)
modules;
}; };
struct limine_module_request { struct limine_module_request {
uint64_t id[4]; uint64_t id[4];
uint64_t revision; uint64_t revision;
LIMINE_PTR(struct limine_module_response *) response; LIMINE_PTR(struct limine_module_response *)
response;
/* Request revision 1 */ /* Request revision 1 */
uint64_t internal_module_count; uint64_t internal_module_count;
LIMINE_PTR(struct limine_internal_module **) internal_modules; LIMINE_PTR(struct limine_internal_module **)
internal_modules;
}; };
/* RSDP */ /* RSDP */
#define LIMINE_RSDP_REQUEST { LIMINE_COMMON_MAGIC, 0xc5e77b6b397e7b43, 0x27637845accdcf3c } #define LIMINE_RSDP_REQUEST \
{ LIMINE_COMMON_MAGIC, 0xc5e77b6b397e7b43, 0x27637845accdcf3c }
struct limine_rsdp_response { struct limine_rsdp_response {
uint64_t revision; uint64_t revision;
LIMINE_PTR(void *) address; LIMINE_PTR(void *)
address;
}; };
struct limine_rsdp_request { struct limine_rsdp_request {
uint64_t id[4]; uint64_t id[4];
uint64_t revision; uint64_t revision;
LIMINE_PTR(struct limine_rsdp_response *) response; LIMINE_PTR(struct limine_rsdp_response *)
response;
}; };
/* SMBIOS */ /* SMBIOS */
#define LIMINE_SMBIOS_REQUEST { LIMINE_COMMON_MAGIC, 0x9e9046f11e095391, 0xaa4a520fefbde5ee } #define LIMINE_SMBIOS_REQUEST \
{ LIMINE_COMMON_MAGIC, 0x9e9046f11e095391, 0xaa4a520fefbde5ee }
struct limine_smbios_response { struct limine_smbios_response {
uint64_t revision; uint64_t revision;
LIMINE_PTR(void *) entry_32; LIMINE_PTR(void *)
LIMINE_PTR(void *) entry_64; entry_32;
LIMINE_PTR(void *)
entry_64;
}; };
struct limine_smbios_request { struct limine_smbios_request {
uint64_t id[4]; uint64_t id[4];
uint64_t revision; uint64_t revision;
LIMINE_PTR(struct limine_smbios_response *) response; LIMINE_PTR(struct limine_smbios_response *)
response;
}; };
/* EFI system table */ /* EFI system table */
#define LIMINE_EFI_SYSTEM_TABLE_REQUEST { LIMINE_COMMON_MAGIC, 0x5ceba5163eaaf6d6, 0x0a6981610cf65fcc } #define LIMINE_EFI_SYSTEM_TABLE_REQUEST \
{ LIMINE_COMMON_MAGIC, 0x5ceba5163eaaf6d6, 0x0a6981610cf65fcc }
struct limine_efi_system_table_response { struct limine_efi_system_table_response {
uint64_t revision; uint64_t revision;
LIMINE_PTR(void *) address; LIMINE_PTR(void *)
address;
}; };
struct limine_efi_system_table_request { struct limine_efi_system_table_request {
uint64_t id[4]; uint64_t id[4];
uint64_t revision; uint64_t revision;
LIMINE_PTR(struct limine_efi_system_table_response *) response; LIMINE_PTR(struct limine_efi_system_table_response *)
response;
}; };
/* Boot time */ /* Boot time */
#define LIMINE_BOOT_TIME_REQUEST { LIMINE_COMMON_MAGIC, 0x502746e184c088aa, 0xfbc5ec83e6327893 } #define LIMINE_BOOT_TIME_REQUEST \
{ LIMINE_COMMON_MAGIC, 0x502746e184c088aa, 0xfbc5ec83e6327893 }
struct limine_boot_time_response { struct limine_boot_time_response {
uint64_t revision; uint64_t revision;
int64_t boot_time; int64_t boot_time;
}; };
struct limine_boot_time_request { struct limine_boot_time_request {
uint64_t id[4]; uint64_t id[4];
uint64_t revision; uint64_t revision;
LIMINE_PTR(struct limine_boot_time_response *) response; LIMINE_PTR(struct limine_boot_time_response *)
response;
}; };
/* Kernel address */ /* Kernel address */
#define LIMINE_KERNEL_ADDRESS_REQUEST { LIMINE_COMMON_MAGIC, 0x71ba76863cc55f63, 0xb2644a48c516a487 } #define LIMINE_KERNEL_ADDRESS_REQUEST \
{ LIMINE_COMMON_MAGIC, 0x71ba76863cc55f63, 0xb2644a48c516a487 }
struct limine_kernel_address_response { struct limine_kernel_address_response {
uint64_t revision; uint64_t revision;
@@ -530,22 +593,26 @@ struct limine_kernel_address_response {
struct limine_kernel_address_request { struct limine_kernel_address_request {
uint64_t id[4]; uint64_t id[4];
uint64_t revision; uint64_t revision;
LIMINE_PTR(struct limine_kernel_address_response *) response; LIMINE_PTR(struct limine_kernel_address_response *)
response;
}; };
/* Device Tree Blob */ /* Device Tree Blob */
#define LIMINE_DTB_REQUEST { LIMINE_COMMON_MAGIC, 0xb40ddb48fb54bac7, 0x545081493f81ffb7 } #define LIMINE_DTB_REQUEST \
{ LIMINE_COMMON_MAGIC, 0xb40ddb48fb54bac7, 0x545081493f81ffb7 }
struct limine_dtb_response { struct limine_dtb_response {
uint64_t revision; uint64_t revision;
LIMINE_PTR(void *) dtb_ptr; LIMINE_PTR(void *)
dtb_ptr;
}; };
struct limine_dtb_request { struct limine_dtb_request {
uint64_t id[4]; uint64_t id[4];
uint64_t revision; uint64_t revision;
LIMINE_PTR(struct limine_dtb_response *) response; LIMINE_PTR(struct limine_dtb_response *)
response;
}; };
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -9,13 +9,13 @@
#include "string.h" #include "string.h"
static volatile struct limine_framebuffer_request framebuffer_request = { static volatile struct limine_framebuffer_request framebuffer_request = {
.id = LIMINE_FRAMEBUFFER_REQUEST, .id = LIMINE_FRAMEBUFFER_REQUEST,
.revision = 0}; .revision = 0};
int framebuffer_count = 0; int framebuffer_count = 0;
struct limine_framebuffer framebuffers[10]; struct limine_framebuffer framebuffers[10];
struct { struct {
void *base; void *base;
uint64_t len; uint64_t len;
} framebufferAddrs[10]; } framebufferAddrs[10];
@@ -35,7 +35,7 @@ void limine_fb_save_response(AddressSpace *boot_address_space) {
void limine_fb_remap(AddressSpace *space) { void limine_fb_remap(AddressSpace *space) {
for (int i = 0; i < framebuffer_count; i++) { for (int i = 0; i < framebuffer_count; i++) {
void *base = framebuffers[i].address; void *base = framebuffers[i].address;
void *realbase = framebufferAddrs[i].base; void *realbase = framebufferAddrs[i].base;
// TODO: Proper map // TODO: Proper map
for (int i = 0; i < 100000; i++) { for (int i = 0; i < 100000; i++) {

View File

@@ -9,11 +9,11 @@
#include "paging.hpp" #include "paging.hpp"
void limine_fb_save_response(struct AddressSpace *boot_address_space); void limine_fb_save_response(struct AddressSpace *boot_address_space);
void limine_fb_remap(struct AddressSpace *space); void limine_fb_remap(struct AddressSpace *space);
extern int framebuffer_count; extern int framebuffer_count;
extern struct limine_framebuffer framebuffers[10]; extern struct limine_framebuffer framebuffers[10];
#endif//OS1_LIMINE_FB_H #endif //OS1_LIMINE_FB_H

View File

@@ -9,17 +9,17 @@
#include "string.h" #include "string.h"
static volatile struct limine_memmap_request memmap_request = { static volatile struct limine_memmap_request memmap_request = {
.id = LIMINE_MEMMAP_REQUEST, .id = LIMINE_MEMMAP_REQUEST,
.revision = 0}; .revision = 0};
unsigned int limine_mm_count; unsigned int limine_mm_count;
struct limine_memmap_entry limine_mm_entries[LIMINE_MM_MAX]; struct limine_memmap_entry limine_mm_entries[LIMINE_MM_MAX];
unsigned int limine_mm_overflow; unsigned int limine_mm_overflow;
void limine_mm_save_response() { void limine_mm_save_response() {
limine_mm_count = memmap_request.response->entry_count; limine_mm_count = memmap_request.response->entry_count;
if (limine_mm_count > LIMINE_MM_MAX) { if (limine_mm_count > LIMINE_MM_MAX) {
limine_mm_count = LIMINE_MM_MAX; limine_mm_count = LIMINE_MM_MAX;
limine_mm_overflow = 1; limine_mm_overflow = 1;
} else { } else {
limine_mm_overflow = 0; limine_mm_overflow = 0;

View File

@@ -9,10 +9,10 @@
#define LIMINE_MM_MAX 256 #define LIMINE_MM_MAX 256
extern unsigned int limine_mm_count; extern unsigned int limine_mm_count;
extern struct limine_memmap_entry limine_mm_entries[LIMINE_MM_MAX]; extern struct limine_memmap_entry limine_mm_entries[LIMINE_MM_MAX];
extern unsigned int limine_mm_overflow; extern unsigned int limine_mm_overflow;
void limine_mm_save_response(); void limine_mm_save_response();
#endif//OS1_LIMINE_MM_H #endif //OS1_LIMINE_MM_H

View File

@@ -8,16 +8,16 @@
#include "string.h" #include "string.h"
static volatile struct limine_module_request module_request = { static volatile struct limine_module_request module_request = {
.id = LIMINE_MODULE_REQUEST, .id = LIMINE_MODULE_REQUEST,
.revision = 0}; .revision = 0};
limine_file saved_modules[max_saved_modules]; limine_file saved_modules[max_saved_modules];
char saved_modules_data[max_saved_modules][max_saved_module_file_size] __attribute__((aligned(4096))); char saved_modules_data[max_saved_modules][max_saved_module_file_size] __attribute__((aligned(4096)));
char saved_modules_names[max_saved_modules][max_saved_module_name] __attribute__((aligned(4096))); char saved_modules_names[max_saved_modules][max_saved_module_name] __attribute__((aligned(4096)));
unsigned saved_modules_size = 0; unsigned saved_modules_size = 0;
void limine_modules_save() { void limine_modules_save() {
for (int i = 0; i < module_request.response->module_count; i++) { for (int i = 0; i < module_request.response->module_count; i++) {
assert(i < max_saved_modules); assert(i < max_saved_modules);
saved_modules_size++; saved_modules_size++;

View File

@@ -7,15 +7,15 @@
#include "limine.hpp" #include "limine.hpp"
void limine_modules_save(); void limine_modules_save();
static constexpr unsigned max_saved_modules = 2; static constexpr unsigned max_saved_modules = 2;
static constexpr unsigned max_saved_module_file_size = 1024 * 1024; static constexpr unsigned max_saved_module_file_size = 1024 * 1024;
static constexpr unsigned max_saved_module_name = 256; static constexpr unsigned max_saved_module_name = 256;
extern unsigned saved_modules_size; extern unsigned saved_modules_size;
extern limine_file saved_modules[max_saved_modules]; extern limine_file saved_modules[max_saved_modules];
extern char saved_modules_data[max_saved_modules][max_saved_module_file_size] __attribute__((aligned(4096))); extern char saved_modules_data[max_saved_modules][max_saved_module_file_size] __attribute__((aligned(4096)));
extern char saved_modules_names[max_saved_modules][max_saved_module_name] __attribute__((aligned(4096))); extern char saved_modules_names[max_saved_modules][max_saved_module_name] __attribute__((aligned(4096)));
#endif//OS2_LIMINE_MODULES_HPP #endif //OS2_LIMINE_MODULES_HPP

View File

@@ -12,19 +12,19 @@
#include <stddef.h> #include <stddef.h>
#define MAXGB 32ULL #define MAXGB 32ULL
#define BITMAP_SIZE (((MAXGB) *1024ULL * 1024ULL) / (16ULL)) #define BITMAP_SIZE (((MAXGB) * 1024ULL * 1024ULL) / (16ULL))
#define MAX_PID (((BITMAP_SIZE) *4) - 4) #define MAX_PID (((BITMAP_SIZE) * 4) - 4)
// Expected to be nulled by the bootloader // Expected to be nulled by the bootloader
static struct FourPages used_bitmap[BITMAP_SIZE]; static struct FourPages used_bitmap[BITMAP_SIZE];
static Mutex memman_lock; static Mutex memman_lock;
static uint64_t maxPid = 0;// Past the end static uint64_t maxPid = 0; // Past the end
static uint64_t minPid = 0; static uint64_t minPid = 0;
static uint64_t totalMem = 0;// Past the end static uint64_t totalMem = 0; // Past the end
static uint64_t roundup4k(uint64_t addr) { static uint64_t roundup4k(uint64_t addr) {
if ((addr & 0xFFF) == 0) return addr; if ((addr & 0xFFF) == 0) return addr;
else { else {
return (addr + 0x1000) & (~(0xFFFULL)); return (addr + 0x1000) & (~(0xFFFULL));
@@ -40,7 +40,7 @@ static uint64_t rounddown4k(uint64_t addr) {
void setSts(uint64_t pid, enum PageStatus sts) { void setSts(uint64_t pid, enum PageStatus sts) {
uint64_t rounddown = pid & (~(0b11ULL)); uint64_t rounddown = pid & (~(0b11ULL));
uint64_t idx = rounddown >> 2; uint64_t idx = rounddown >> 2;
switch (pid & 0b11ULL) { switch (pid & 0b11ULL) {
case 0: case 0:
used_bitmap[idx].first = sts; used_bitmap[idx].first = sts;
@@ -59,7 +59,7 @@ void setSts(uint64_t pid, enum PageStatus sts) {
enum PageStatus getSts(uint64_t pid) { enum PageStatus getSts(uint64_t pid) {
uint64_t rounddown = pid & (~(0b11ULL)); uint64_t rounddown = pid & (~(0b11ULL));
uint64_t idx = rounddown >> 2; uint64_t idx = rounddown >> 2;
switch (pid & 0b11ULL) { switch (pid & 0b11ULL) {
case 0: case 0:
return used_bitmap[idx].first; return used_bitmap[idx].first;

View File

@@ -7,23 +7,23 @@
#include "limine.h" #include "limine.h"
enum PageStatus { enum PageStatus {
MEMMAN_STATE_FREE = 1, MEMMAN_STATE_FREE = 1,
MEMMAN_STATE_USED = 2, MEMMAN_STATE_USED = 2,
MEMMAN_STATE_RESERVED = 0, MEMMAN_STATE_RESERVED = 0,
MEMMAN_STATE_RECLAIMABLE = 3, MEMMAN_STATE_RECLAIMABLE = 3,
}; };
struct FourPages { struct FourPages {
enum PageStatus first : 2; enum PageStatus first : 2;
enum PageStatus second : 2; enum PageStatus second : 2;
enum PageStatus third : 2; enum PageStatus third : 2;
enum PageStatus fourth : 2; enum PageStatus fourth : 2;
}; };
void parse_limine_memmap(struct limine_memmap_entry *entries, unsigned int num, uint64_t what_is_considered_free); void parse_limine_memmap(struct limine_memmap_entry *entries, unsigned int num, uint64_t what_is_considered_free);
void *get4k(); void *get4k();
void free4k(void *page); void free4k(void *page);
uint64_t get_free(); uint64_t get_free();
#endif//OS1_MEMMAN_H #endif //OS1_MEMMAN_H

View File

@@ -35,8 +35,8 @@ char *itoa(int value, char *str, int base) {
// Invert the numbers. // Invert the numbers.
while (low < ptr) { while (low < ptr) {
char tmp = *low; char tmp = *low;
*low++ = *ptr; *low++ = *ptr;
*ptr-- = tmp; *ptr-- = tmp;
} }
return rc; return rc;
} }

View File

@@ -71,7 +71,7 @@ static inline void irqrestore(unsigned long flags) {
} }
static inline void wrmsr(uint64_t msr, uint64_t value) { static inline void wrmsr(uint64_t msr, uint64_t value) {
uint32_t low = value & 0xFFFFFFFF; uint32_t low = value & 0xFFFFFFFF;
uint32_t high = value >> 32; uint32_t high = value >> 32;
asm volatile( asm volatile(
"wrmsr" "wrmsr"

View File

@@ -47,10 +47,10 @@ void *AddressSpace::virt2real(void *virt) {
assert2((uint64_t) PML4 >= HHDM_BEGIN, "CR3 here must be in HDDM!"); assert2((uint64_t) PML4 >= HHDM_BEGIN, "CR3 here must be in HDDM!");
assert2((uint64_t) PML4 < kernel_virt_base, "CR3 here must be in HDDM!"); assert2((uint64_t) PML4 < kernel_virt_base, "CR3 here must be in HDDM!");
uint64_t pml4i = (uint64_t) virt >> 39 & 0x01FF; uint64_t pml4i = (uint64_t) virt >> 39 & 0x01FF;
uint64_t pdpei = (uint64_t) virt >> 30 & 0x01FF; uint64_t pdpei = (uint64_t) virt >> 30 & 0x01FF;
uint64_t pdei = (uint64_t) virt >> 21 & 0x01FF; uint64_t pdei = (uint64_t) virt >> 21 & 0x01FF;
uint64_t ptsi = (uint64_t) virt >> 12 & 0x01FF; uint64_t ptsi = (uint64_t) virt >> 12 & 0x01FF;
uint64_t *pml4e = PML4 + pml4i; uint64_t *pml4e = PML4 + pml4i;
if (!((*pml4e) & PAGE_PRESENT)) return 0; if (!((*pml4e) & PAGE_PRESENT)) return 0;
@@ -82,10 +82,10 @@ int AddressSpace::map(void *virt, void *real, uint32_t flags) {
assert2((uint64_t) PML4 >= HHDM_BEGIN, "CR3 here must be in HDDM!"); assert2((uint64_t) PML4 >= HHDM_BEGIN, "CR3 here must be in HDDM!");
assert2((uint64_t) PML4 < kernel_virt_base, "CR3 here must be in HDDM!"); assert2((uint64_t) PML4 < kernel_virt_base, "CR3 here must be in HDDM!");
uint64_t pml4i = (uint64_t) virt >> 39 & 0x01FF; uint64_t pml4i = (uint64_t) virt >> 39 & 0x01FF;
uint64_t pdpei = (uint64_t) virt >> 30 & 0x01FF; uint64_t pdpei = (uint64_t) virt >> 30 & 0x01FF;
uint64_t pdei = (uint64_t) virt >> 21 & 0x01FF; uint64_t pdei = (uint64_t) virt >> 21 & 0x01FF;
uint64_t ptsi = (uint64_t) virt >> 12 & 0x01FF; uint64_t ptsi = (uint64_t) virt >> 12 & 0x01FF;
uint64_t *pml4e = PML4 + pml4i; uint64_t *pml4e = PML4 + pml4i;
@@ -125,7 +125,7 @@ int AddressSpace::map(void *virt, void *real, uint32_t flags) {
uint64_t *ptsb = (uint64_t *) HHDM_P2V((*pdee & 0x000FFFFFFFFFF000ULL)); uint64_t *ptsb = (uint64_t *) HHDM_P2V((*pdee & 0x000FFFFFFFFFF000ULL));
uint64_t *ptse = &ptsb[ptsi]; uint64_t *ptse = &ptsb[ptsi];
*ptse = ((uint64_t) real & 0x000FFFFFFFFFF000ULL) | (flags & 0xFFF) | PAGE_PRESENT; *ptse = ((uint64_t) real & 0x000FFFFFFFFFF000ULL) | (flags & 0xFFF) | PAGE_PRESENT;
invlpg((void *) ((uint64_t) virt & 0x000FFFFFFFFFF000ULL)); invlpg((void *) ((uint64_t) virt & 0x000FFFFFFFFFF000ULL));
return 1; return 1;
} }
@@ -136,10 +136,10 @@ int AddressSpace::unmap(void *virt) {
assert2((uint64_t) PML4 >= HHDM_BEGIN, "CR3 here must be in HDDM!"); assert2((uint64_t) PML4 >= HHDM_BEGIN, "CR3 here must be in HDDM!");
assert2((uint64_t) PML4 < kernel_virt_base, "CR3 here must be in HDDM!"); assert2((uint64_t) PML4 < kernel_virt_base, "CR3 here must be in HDDM!");
uint64_t pml4i = (uint64_t) virt >> 39 & 0x01FF; uint64_t pml4i = (uint64_t) virt >> 39 & 0x01FF;
uint64_t pdpei = (uint64_t) virt >> 30 & 0x01FF; uint64_t pdpei = (uint64_t) virt >> 30 & 0x01FF;
uint64_t pdei = (uint64_t) virt >> 21 & 0x01FF; uint64_t pdei = (uint64_t) virt >> 21 & 0x01FF;
uint64_t ptsi = (uint64_t) virt >> 12 & 0x01FF; uint64_t ptsi = (uint64_t) virt >> 12 & 0x01FF;
uint64_t *pml4e = PML4 + pml4i; uint64_t *pml4e = PML4 + pml4i;
@@ -168,7 +168,7 @@ FDT *AddressSpace::getFdt() {
} }
static volatile struct limine_kernel_address_request kernel_address_request = { static volatile struct limine_kernel_address_request kernel_address_request = {
.id = LIMINE_KERNEL_ADDRESS_REQUEST, .id = LIMINE_KERNEL_ADDRESS_REQUEST,
.revision = 0}; .revision = 0};
void limine_kern_save_response() { void limine_kern_save_response() {
@@ -180,10 +180,10 @@ void limine_kern_save_response() {
static uint64_t early_pages[EARLY_PAGES_SIZE][512] __attribute__((aligned(PAGE_SIZE))); static uint64_t early_pages[EARLY_PAGES_SIZE][512] __attribute__((aligned(PAGE_SIZE)));
static uint64_t early_pages_used = 0; static uint64_t early_pages_used = 0;
uintptr_t kernel_phys_base; uintptr_t kernel_phys_base;
uintptr_t kernel_virt_base; uintptr_t kernel_virt_base;
void map_hddm(uint64_t *pml4) { void map_hddm(uint64_t *pml4) {
assert2(kernel_virt_base != 0, "Kernel virt address not loaded!"); assert2(kernel_virt_base != 0, "Kernel virt address not loaded!");
assert2(kernel_phys_base != 0, "Kernel phys address not loaded!"); assert2(kernel_phys_base != 0, "Kernel phys address not loaded!");
@@ -191,8 +191,8 @@ void map_hddm(uint64_t *pml4) {
// Which is true if the first bytes of memory, where the kernel is are identity mapped, // Which is true if the first bytes of memory, where the kernel is are identity mapped,
// Which is true if we're using Limine // Which is true if we're using Limine
for (uint64_t i = 0; i < HHDM_SIZE; i++) { for (uint64_t i = 0; i < HHDM_SIZE; i++) {
void *virt = (void *) (HHDM_BEGIN + i * 1024ULL * 1024ULL * 1024ULL); void *virt = (void *) (HHDM_BEGIN + i * 1024ULL * 1024ULL * 1024ULL);
void *real = (void *) (i * 1024ULL * 1024ULL * 1024ULL); void *real = (void *) (i * 1024ULL * 1024ULL * 1024ULL);
uint64_t pml4i = (uint64_t) virt >> 39 & 0x01FF; uint64_t pml4i = (uint64_t) virt >> 39 & 0x01FF;
uint64_t pdpei = (uint64_t) virt >> 30 & 0x01FF; uint64_t pdpei = (uint64_t) virt >> 30 & 0x01FF;

View File

@@ -10,13 +10,13 @@
#include "PointersCollection.hpp" #include "PointersCollection.hpp"
#define PAGE_SIZE 4096 #define PAGE_SIZE 4096
#define KERN_V2P(a) ((((uintptr_t) (a) + kernel_phys_base) & ~kernel_virt_base)) #define KERN_V2P(a) ((((uintptr_t) (a) + kernel_phys_base) & ~kernel_virt_base))
#define KERN_P2V(a) ((((uintptr_t) (a) -kernel_phys_base) | kernel_virt_base)) #define KERN_P2V(a) ((((uintptr_t) (a) -kernel_phys_base) | kernel_virt_base))
#define HHDM_BEGIN 0xfffff80000000000ULL #define HHDM_BEGIN 0xfffff80000000000ULL
#define HHDM_SIZE 32ULL// In GB #define HHDM_SIZE 32ULL // In GB
#define HHDM_V2P(a) ((((uintptr_t) (a)) & ~HHDM_BEGIN)) #define HHDM_V2P(a) ((((uintptr_t) (a)) & ~HHDM_BEGIN))
#define HHDM_P2V(a) ((((uintptr_t) (a)) | HHDM_BEGIN)) #define HHDM_P2V(a) ((((uintptr_t) (a)) | HHDM_BEGIN))
@@ -28,9 +28,9 @@ public:
AddressSpace(uint64_t *PML4); AddressSpace(uint64_t *PML4);
~AddressSpace(); ~AddressSpace();
void *virt2real(void *virt); void *virt2real(void *virt);
int map(void *virt, void *real, uint32_t flags); int map(void *virt, void *real, uint32_t flags);
int unmap(void *virt); int unmap(void *virt);
uint64_t *get_cr3() { uint64_t *get_cr3() {
return PML4; return PML4;
@@ -46,22 +46,22 @@ private:
// Pointer to PML4 in HDDM // Pointer to PML4 in HDDM
uint64_t *PML4; uint64_t *PML4;
FDT *_fdt = nullptr; FDT *_fdt = nullptr;
}; };
extern AddressSpace *KERN_AddressSpace; extern AddressSpace *KERN_AddressSpace;
extern uintptr_t kernel_phys_base; extern uintptr_t kernel_phys_base;
extern uintptr_t kernel_virt_base; extern uintptr_t kernel_virt_base;
void limine_kern_save_response(); void limine_kern_save_response();
#define PAGE_PS (1 << 7) #define PAGE_PS (1 << 7)
#define PAGE_RW (1 << 1) #define PAGE_RW (1 << 1)
#define PAGE_USER (1 << 2) #define PAGE_USER (1 << 2)
#define PAGE_PRESENT (0x01ULL) #define PAGE_PRESENT (0x01ULL)
void map_hddm(uint64_t *pml4); void map_hddm(uint64_t *pml4);
extern "C" void _tlb_flush(); extern "C" void _tlb_flush();
#endif//OS1_PAGING_H #endif //OS1_PAGING_H

View File

@@ -9,18 +9,18 @@
#include "io.hpp" #include "io.hpp"
#include "task.hpp" #include "task.hpp"
#define PORT 0x3f8// COM1 #define PORT 0x3f8 // COM1
int init_serial() { int init_serial() {
outb(PORT + 1, 0x00);// Disable all interrupts outb(PORT + 1, 0x00); // Disable all interrupts
outb(PORT + 3, 0x80);// Enable DLAB (set baud rate divisor) outb(PORT + 3, 0x80); // Enable DLAB (set baud rate divisor)
outb(PORT + 0, 0x03);// Set divisor to 3 (lo byte) 38400 baud outb(PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud
outb(PORT + 1, 0x00);// (hi byte) outb(PORT + 1, 0x00); // (hi byte)
outb(PORT + 3, 0x03);// 8 bits, no parity, one stop bit outb(PORT + 3, 0x03); // 8 bits, no parity, one stop bit
outb(PORT + 2, 0xC7);// Enable FIFO, clear them, with 14-byte threshold outb(PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
outb(PORT + 4, 0x0B);// IRQs enabled, RTS/DSR set outb(PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set
outb(PORT + 4, 0x1E);// Set in loopback mode, test the serial chip outb(PORT + 4, 0x1E); // Set in loopback mode, test the serial chip
outb(PORT + 0, 0xAE);// Test serial chip (send byte 0xAE and check if serial returns same byte) outb(PORT + 0, 0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte)
// Check if serial is faulty (i.e: not same byte as sent) // Check if serial is faulty (i.e: not same byte as sent)
if (inb(PORT + 0) != 0xAE) { if (inb(PORT + 0) != 0xAE) {

View File

@@ -7,15 +7,15 @@
#include "misc.hpp" #include "misc.hpp"
int init_serial(); int init_serial();
int serial_received(); int serial_received();
char read_serial(); char read_serial();
int is_transmit_empty(); int is_transmit_empty();
void write_serial(char a); void write_serial(char a);
void writestr(const char *a); void writestr(const char *a);
void write_serial_no_yield(char a); void write_serial_no_yield(char a);
void writestr_no_yield(const char *a); void writestr_no_yield(const char *a);
#endif//OS1_SERIAL_H #endif //OS1_SERIAL_H

View File

@@ -20,30 +20,30 @@
// even with completely broken 16-bit segments somehow // even with completely broken 16-bit segments somehow
// But what happens with something more complex is completely bonkers // But what happens with something more complex is completely bonkers
struct STAR { struct STAR {
unsigned unused : 32; unsigned unused : 32;
unsigned call_cs_ss : 16; unsigned call_cs_ss : 16;
unsigned ret_cs_ss : 16; unsigned ret_cs_ss : 16;
} __attribute__((packed)); } __attribute__((packed));
static_assert(sizeof(STAR) == 8); static_assert(sizeof(STAR) == 8);
void setup_syscalls() { void setup_syscalls() {
union { union {
STAR star; STAR star;
uint64_t bytes; uint64_t bytes;
} __attribute__((__packed__)) newstar{}; } __attribute__((__packed__)) newstar{};
newstar.star.ret_cs_ss = (GDTSEL(gdt_data_user) - 8) | 0x3; newstar.star.ret_cs_ss = (Arch::GDT::gdt_data_user.selector() - 8) | 0x3;
assert(newstar.star.ret_cs_ss + 8 == (GDTSEL(gdt_data_user) | 0x3)); assert(newstar.star.ret_cs_ss + 8 == (Arch::GDT::gdt_data_user.selector() | 0x3));
assert(newstar.star.ret_cs_ss + 16 == (GDTSEL(gdt_code_user) | 0x3)); assert(newstar.star.ret_cs_ss + 16 == (Arch::GDT::gdt_code_user.selector() | 0x3));
newstar.star.call_cs_ss = (GDTSEL(gdt_code)); newstar.star.call_cs_ss = (Arch::GDT::gdt_code.selector());
assert(newstar.star.call_cs_ss == GDTSEL(gdt_code)); assert(newstar.star.call_cs_ss == Arch::GDT::gdt_code.selector());
assert(newstar.star.call_cs_ss + 8 == GDTSEL(gdt_data)); assert(newstar.star.call_cs_ss + 8 == Arch::GDT::gdt_data.selector());
wrmsr(0xc0000081, newstar.bytes); wrmsr(0xc0000081, newstar.bytes);
wrmsr(0xc0000082, reinterpret_cast<uint64_t>(&_syscall_entrypoint)); wrmsr(0xc0000082, reinterpret_cast<uint64_t>(&_syscall_entrypoint));
wrmsr(0xc0000084, (1 << 9));// IA32_FMASK, mask interrupts wrmsr(0xc0000084, (1 << 9)); // IA32_FMASK, mask interrupts
wrmsr(0xC0000080, rdmsr(0xC0000080) | 0b1); wrmsr(0xC0000080, rdmsr(0xC0000080) | 0b1);
} }

View File

@@ -7,9 +7,9 @@
#include <cstdint> #include <cstdint>
void setup_syscalls(); void setup_syscalls();
extern "C" void _syscall_entrypoint(); extern "C" void _syscall_entrypoint();
extern "C" uint64_t syscall_impl(uint64_t id_rdi, uint64_t a1_rsi, uint64_t a2_rdx, uint64_t a3_rcx); extern "C" uint64_t syscall_impl(uint64_t id_rdi, uint64_t a1_rsi, uint64_t a2_rdx, uint64_t a3_rcx);
#endif//OS2_SYSCALLS_HPP #endif //OS2_SYSCALLS_HPP

View File

@@ -30,32 +30,32 @@ void sanity_check_frame(struct task_frame *cur_frame) {
assert(cur_frame->ss != 0); assert(cur_frame->ss != 0);
assert(cur_frame->cs != 0); assert(cur_frame->cs != 0);
assert(cur_frame->sp != 0); assert(cur_frame->sp != 0);
assert2((cur_frame->ss == GDTSEL(gdt_data) || (cur_frame->ss == GDTSEL(gdt_data_user)) | 0x3), "SS wrong!"); assert2((cur_frame->ss == Arch::GDT::gdt_data.selector() || (cur_frame->ss == Arch::GDT::gdt_data_user.selector()) | 0x3), "SS wrong!");
assert2((cur_frame->cs == GDTSEL(gdt_code) || (cur_frame->ss == GDTSEL(gdt_code_user)) | 0x3), "CS wrong!"); assert2((cur_frame->cs == Arch::GDT::gdt_code.selector() || (cur_frame->ss == Arch::GDT::gdt_code_user.selector()) | 0x3), "CS wrong!");
} }
std::atomic<uint64_t> max_pid = 0; std::atomic<uint64_t> max_pid = 0;
Mutex AllTasks_lock; Mutex AllTasks_lock;
SkipList<uint64_t, Task *> AllTasks; SkipList<uint64_t, Task *> AllTasks;
static List<Task *>::Node *RunningTask; static List<Task *>::Node *RunningTask;
static Spinlock NextTasks_lock; static Spinlock NextTasks_lock;
static List<Task *> NextTasks; static List<Task *> NextTasks;
// Task freer // Task freer
Mutex TasksToFree_lock; Mutex TasksToFree_lock;
CV TasksToFree_cv; CV TasksToFree_cv;
List<List<Task *>::Node *> TasksToFree; List<List<Task *>::Node *> TasksToFree;
// Waiting // Waiting
Mutex WaitingTasks_mlock; Mutex WaitingTasks_mlock;
CV WaitingTasks_cv; CV WaitingTasks_cv;
SkipList<uint64_t, List<Task *>::Node *> WaitingTasks; SkipList<uint64_t, List<Task *>::Node *> WaitingTasks;
static std::atomic<bool> initialized = false; static std::atomic<bool> initialized = false;
static void free_task(struct Task *t) { static void free_task(struct Task *t) {
kfree(t->kstack); kfree(t->kstack);
kfree(t->name); kfree(t->name);
kfree(t->fxsave); kfree(t->fxsave);
@@ -110,28 +110,28 @@ static void task_freer() {
struct Task *new_ktask(void (*fn)(), const char *name, bool start) { struct Task *new_ktask(void (*fn)(), const char *name, bool start) {
struct Task *newt = static_cast<Task *>(kmalloc(sizeof(struct Task))); struct Task *newt = static_cast<Task *>(kmalloc(sizeof(struct Task)));
newt->kstack = static_cast<uint64_t *>(kmalloc(TASK_SS)); newt->kstack = static_cast<uint64_t *>(kmalloc(TASK_SS));
newt->name = static_cast<char *>(kmalloc(strlen(name) + 1)); newt->name = static_cast<char *>(kmalloc(strlen(name) + 1));
newt->fxsave = static_cast<char *>(kmalloc(512)); newt->fxsave = static_cast<char *>(kmalloc(512));
strcpy(name, newt->name); strcpy(name, newt->name);
newt->frame.sp = ((((uintptr_t) newt->kstack) + (TASK_SS - 9) - 1) & (~0xFULL)) + 8;// Ensure 16byte alignment newt->frame.sp = ((((uintptr_t) newt->kstack) + (TASK_SS - 9) - 1) & (~0xFULL)) + 8; // Ensure 16byte alignment
// It should be aligned before call, therefore on function entry it should be misaligned by 8 bytes // It should be aligned before call, therefore on function entry it should be misaligned by 8 bytes
assert((newt->frame.sp & 0xFULL) == 8); assert((newt->frame.sp & 0xFULL) == 8);
newt->frame.ip = (uint64_t) fn; newt->frame.ip = (uint64_t) fn;
newt->frame.cs = GDTSEL(gdt_code); newt->frame.cs = Arch::GDT::gdt_code.selector();
newt->frame.ss = GDTSEL(gdt_data); newt->frame.ss = Arch::GDT::gdt_data.selector();
for (int i = 0; i < 512; i++) newt->fxsave[i] = 0; for (int i = 0; i < 512; i++) newt->fxsave[i] = 0;
newt->frame.flags = flags(); newt->frame.flags = flags();
newt->frame.guard = IDT_GUARD; newt->frame.guard = IDT_GUARD;
newt->addressSpace = KERN_AddressSpace; newt->addressSpace = KERN_AddressSpace;
newt->state = start ? TS_RUNNING : TS_BLOCKED; newt->state = start ? TS_RUNNING : TS_BLOCKED;
newt->mode = TASKMODE_KERN; newt->mode = TASKMODE_KERN;
newt->pid = max_pid.fetch_add(1); newt->pid = max_pid.fetch_add(1);
newt->used_time = 0; newt->used_time = 0;
sanity_check_frame(&newt->frame); sanity_check_frame(&newt->frame);
if (start) { if (start) {
@@ -150,45 +150,45 @@ struct Task *new_ktask(void (*fn)(), const char *name, bool start) {
return newt; return newt;
} }
struct Task *new_utask(void (*entrypoint)(), const char *name) { struct Task *new_utask(void (*entrypoint)(), const char *name) {
Task *newt = static_cast<Task *>(kmalloc(sizeof(struct Task))); Task *newt = static_cast<Task *>(kmalloc(sizeof(struct Task)));
newt->kstack = static_cast<uint64_t *>(kmalloc(TASK_SS)); newt->kstack = static_cast<uint64_t *>(kmalloc(TASK_SS));
newt->name = static_cast<char *>(kmalloc(strlen(name) + 1)); newt->name = static_cast<char *>(kmalloc(strlen(name) + 1));
newt->fxsave = static_cast<char *>(kmalloc(512)); newt->fxsave = static_cast<char *>(kmalloc(512));
strcpy(name, newt->name); strcpy(name, newt->name);
newt->frame.ip = (uint64_t) entrypoint; newt->frame.ip = (uint64_t) entrypoint;
newt->frame.cs = GDTSEL(gdt_code_user) | 0x3; newt->frame.cs = Arch::GDT::gdt_code_user.selector() | 0x3;
newt->frame.ss = GDTSEL(gdt_data_user) | 0x3; newt->frame.ss = Arch::GDT::gdt_data_user.selector() | 0x3;
for (int i = 0; i < 512; i++) newt->fxsave[i] = 0; for (int i = 0; i < 512; i++) newt->fxsave[i] = 0;
newt->frame.flags = flags(); newt->frame.flags = flags();
newt->frame.guard = IDT_GUARD; newt->frame.guard = IDT_GUARD;
newt->addressSpace = new AddressSpace(); newt->addressSpace = new AddressSpace();
newt->vma = new VMA(newt->addressSpace); newt->vma = new VMA(newt->addressSpace);
newt->state = TS_BLOCKED; newt->state = TS_BLOCKED;
newt->mode = TASKMODE_USER; newt->mode = TASKMODE_USER;
newt->pid = max_pid.fetch_add(1); newt->pid = max_pid.fetch_add(1);
newt->used_time = 0; newt->used_time = 0;
task_pointer *taskptr = static_cast<task_pointer *>( task_pointer *taskptr = static_cast<task_pointer *>(
newt->vma->mmap_mem(reinterpret_cast<void *>(TASK_POINTER), newt->vma->mmap_mem(reinterpret_cast<void *>(TASK_POINTER),
sizeof(task_pointer), 0, PAGE_RW | PAGE_USER));// FIXME: this is probably unsafe sizeof(task_pointer), 0, PAGE_RW | PAGE_USER)); // FIXME: this is probably unsafe
assert((uintptr_t) taskptr == TASK_POINTER); assert((uintptr_t) taskptr == TASK_POINTER);
task_pointer *taskptr_real = reinterpret_cast<task_pointer *>(HHDM_P2V(newt->addressSpace->virt2real(taskptr))); task_pointer *taskptr_real = reinterpret_cast<task_pointer *>(HHDM_P2V(newt->addressSpace->virt2real(taskptr)));
newt->entry_ksp_val = ((((uintptr_t) newt->kstack) + (TASK_SS - 9) - 1) & (~0xFULL));// Ensure 16byte alignment newt->entry_ksp_val = ((((uintptr_t) newt->kstack) + (TASK_SS - 9) - 1) & (~0xFULL)); // Ensure 16byte alignment
// It should be aligned before call, therefore it actually should be aligned here // It should be aligned before call, therefore it actually should be aligned here
assert((newt->entry_ksp_val & 0xFULL) == 0); assert((newt->entry_ksp_val & 0xFULL) == 0);
taskptr_real->taskptr = newt; taskptr_real->taskptr = newt;
taskptr_real->entry_ksp_val = newt->entry_ksp_val; taskptr_real->entry_ksp_val = newt->entry_ksp_val;
taskptr_real->ret_sp = 0x0; taskptr_real->ret_sp = 0x0;
void *ustack = newt->vma->mmap_mem(NULL, TASK_SS, 0, PAGE_RW | PAGE_USER); void *ustack = newt->vma->mmap_mem(NULL, TASK_SS, 0, PAGE_RW | PAGE_USER);
newt->frame.sp = ((((uintptr_t) ustack) + (TASK_SS - 17) - 1) & (~0xFULL)) + 8;// Ensure 16byte alignment newt->frame.sp = ((((uintptr_t) ustack) + (TASK_SS - 17) - 1) & (~0xFULL)) + 8; // Ensure 16byte alignment
// It should be aligned before call, therefore on function entry it should be misaligned by 8 bytes // It should be aligned before call, therefore on function entry it should be misaligned by 8 bytes
assert((newt->frame.sp & 0xFULL) == 8); assert((newt->frame.sp & 0xFULL) == 8);
@@ -205,7 +205,7 @@ struct Task *new_utask(void (*entrypoint)(), const char *name) {
List<Task *>::Node *start_task(struct Task *task) { List<Task *>::Node *start_task(struct Task *task) {
assert(task->state != TS_RUNNING); assert(task->state != TS_RUNNING);
task->state = TS_RUNNING; task->state = TS_RUNNING;
auto new_node = NextTasks.create_node(task); auto new_node = NextTasks.create_node(task);
{ {
SpinlockLockNoInt l(NextTasks_lock); SpinlockLockNoInt l(NextTasks_lock);
@@ -267,7 +267,7 @@ static void task_waker() {
while (WaitingTasks.begin() != WaitingTasks.end() && WaitingTasks.begin()->key <= micros && WaitingTasks.begin()->data->val->state != TS_RUNNING) { while (WaitingTasks.begin() != WaitingTasks.end() && WaitingTasks.begin()->key <= micros && WaitingTasks.begin()->data->val->state != TS_RUNNING) {
auto *node = &*WaitingTasks.begin(); auto *node = &*WaitingTasks.begin();
auto task = WaitingTasks.begin()->data; auto task = WaitingTasks.begin()->data;
// TODO this is all ugly // TODO this is all ugly
uint64_t l1 = 0; uint64_t l1 = 0;
@@ -282,7 +282,7 @@ static void task_waker() {
assert(l1 - l2 == 1); assert(l1 - l2 == 1);
task->val->sleep_until = 0; task->val->sleep_until = 0;
task->val->state = TS_RUNNING; task->val->state = TS_RUNNING;
{ {
SpinlockLockNoInt l(NextTasks_lock); SpinlockLockNoInt l(NextTasks_lock);
@@ -325,15 +325,15 @@ extern "C" void switch_task(struct task_frame *cur_frame) {
} }
} }
AddressSpace *oldspace = nullptr; AddressSpace *oldspace = nullptr;
List<Task *>::Node *next; List<Task *>::Node *next;
{ {
SpinlockLockNoIntAssert ntl(NextTasks_lock); SpinlockLockNoIntAssert ntl(NextTasks_lock);
static uint64_t lastSwitchMicros = 0; static uint64_t lastSwitchMicros = 0;
uint64_t prevSwitchMicros = lastSwitchMicros; uint64_t prevSwitchMicros = lastSwitchMicros;
lastSwitchMicros = micros; lastSwitchMicros = micros;
if (RunningTask) { if (RunningTask) {
RunningTask->val->frame = *cur_frame; RunningTask->val->frame = *cur_frame;
@@ -352,7 +352,7 @@ extern "C" void switch_task(struct task_frame *cur_frame) {
} }
RunningTask = next; RunningTask = next;
*cur_frame = RunningTask->val->frame; *cur_frame = RunningTask->val->frame;
__builtin_memcpy(temp_fxsave, RunningTask->val->fxsave, 512); __builtin_memcpy(temp_fxsave, RunningTask->val->fxsave, 512);
AddressSpace *newspace = RunningTask->val->addressSpace; AddressSpace *newspace = RunningTask->val->addressSpace;

View File

@@ -28,43 +28,43 @@ struct AddressSpace;
class VMA; class VMA;
struct Task { struct Task {
uint64_t entry_ksp_val; uint64_t entry_ksp_val;
struct task_frame frame; struct task_frame frame;
uint64_t pid; uint64_t pid;
std::atomic<uint64_t> used_time; std::atomic<uint64_t> used_time;
AddressSpace *addressSpace; AddressSpace *addressSpace;
VMA *vma; VMA *vma;
uint64_t *kstack; uint64_t *kstack;
char *fxsave; char *fxsave;
char *name; char *name;
enum TaskMode mode; enum TaskMode mode;
uint64_t sleep_until; uint64_t sleep_until;
enum TaskState state; enum TaskState state;
}; };
struct task_pointer { struct task_pointer {
Task *taskptr; Task *taskptr;
uint64_t entry_ksp_val; uint64_t entry_ksp_val;
uint64_t ret_sp; uint64_t ret_sp;
uint64_t ret_flags; uint64_t ret_flags;
} __attribute__((packed)); } __attribute__((packed));
struct Task *cur_task(); struct Task *cur_task();
List<Task *>::Node *extract_running_task_node(); List<Task *>::Node *extract_running_task_node();
void init_tasks(); void init_tasks();
struct Task *new_ktask(void (*fn)(), const char *name, bool start = true); struct Task *new_ktask(void (*fn)(), const char *name, bool start = true);
struct Task *new_utask(void (*entrypoint)(), const char *name); struct Task *new_utask(void (*entrypoint)(), const char *name);
List<Task *>::Node *start_task(struct Task *task); List<Task *>::Node *start_task(struct Task *task);
void remove_self(); void remove_self();
void sleep_self(uint64_t diff); void sleep_self(uint64_t diff);
void self_block(); void self_block();
class Spinlock; class Spinlock;
void self_block(Spinlock &to_unlock); void self_block(Spinlock &to_unlock);
void unblock(Task *what); void unblock(Task *what);
void unblock(List<Task *>::Node *what); void unblock(List<Task *>::Node *what);
extern "C" void switch_task(struct task_frame *cur_frame); extern "C" void switch_task(struct task_frame *cur_frame);
@@ -73,8 +73,8 @@ using TaskPID = uint64_t;
// TODO: that's quite inefficient! // TODO: that's quite inefficient!
SkipList<uint64_t, std::pair<String, TaskPID>> getTaskTimePerPid(); SkipList<uint64_t, std::pair<String, TaskPID>> getTaskTimePerPid();
void yield_self(); void yield_self();
extern "C" void _yield_self_kern();// Expects the caller to save interrupt state extern "C" void _yield_self_kern(); // Expects the caller to save interrupt state
#endif//OS1_TASK_H #endif //OS1_TASK_H

View File

@@ -10,7 +10,7 @@
volatile std::atomic<uint64_t> ticks; volatile std::atomic<uint64_t> ticks;
volatile std::atomic<uint64_t> micros; volatile std::atomic<uint64_t> micros;
unsigned read_pit_count(void) { unsigned read_pit_count(void) {
unsigned count = 0; unsigned count = 0;
// Disable interrupts // Disable interrupts
@@ -19,8 +19,8 @@ unsigned read_pit_count(void) {
// al = channel in bits 6 and 7, remaining bits clear // al = channel in bits 6 and 7, remaining bits clear
outb(0x43, 0b0000000); outb(0x43, 0b0000000);
count = inb(0x40); // Low byte count = inb(0x40); // Low byte
count |= inb(0x40) << 8;// High byte count |= inb(0x40) << 8; // High byte
return count; return count;
} }
@@ -30,15 +30,15 @@ void set_pit_count(unsigned count) {
// cli(); // cli();
// Set low byte // Set low byte
outb(0x40, count & 0xFF); // Low byte outb(0x40, count & 0xFF); // Low byte
outb(0x40, (count & 0xFF00) >> 8);// High byte outb(0x40, (count & 0xFF00) >> 8); // High byte
return; return;
} }
// Very rough but I don't care right now // Very rough but I don't care right now
// About 1000 HZ freq // About 1000 HZ freq
#define RELOAD_VAL 1193 #define RELOAD_VAL 1193
#define FREQ (1193182 / (RELOAD_VAL)) #define FREQ (1193182 / (RELOAD_VAL))
#define MICROS_PER_TICK (1000000 / (FREQ)) #define MICROS_PER_TICK (1000000 / (FREQ))
void init_timer() { void init_timer() {

View File

@@ -11,7 +11,7 @@
extern volatile std::atomic<uint64_t> ticks; extern volatile std::atomic<uint64_t> ticks;
extern volatile std::atomic<uint64_t> micros; extern volatile std::atomic<uint64_t> micros;
void init_timer(); void init_timer();
void timer_tick(); void timer_tick();
#endif//OS1_TIMER_H #endif //OS1_TIMER_H

View File

@@ -36,7 +36,7 @@ BytesFormatter::BytesFormat BytesFormatter::format(unsigned long long int bytes)
} }
String BytesFormatter::formatStr(unsigned long long int bytes) { String BytesFormatter::formatStr(unsigned long long int bytes) {
auto fmt = format(bytes); auto fmt = format(bytes);
String out; String out;
out += fmt.number; out += fmt.number;
out += " "; out += " ";

View File

@@ -12,8 +12,8 @@ class BytesFormatter {
public: public:
/// Structure for returning the processed byte value /// Structure for returning the processed byte value
struct BytesFormat { struct BytesFormat {
String number;///< Number part of the value String number; ///< Number part of the value
String prefix;///< Unit of measure String prefix; ///< Unit of measure
}; };
/// Formats the bytes in BytesFormat format /// Formats the bytes in BytesFormat format
@@ -28,4 +28,4 @@ public:
}; };
#endif//OS2_BYTESFORMATTER_HPP #endif //OS2_BYTESFORMATTER_HPP

View File

@@ -44,9 +44,9 @@ public:
} }
private: private:
T *_lock; T *_lock;
bool suc; bool suc;
}; };
#endif//OS2_LOCKGUARD_H #endif //OS2_LOCKGUARD_H

View File

@@ -24,7 +24,7 @@ public:
void spinlock() { void spinlock() {
assert2(!are_interrupts_enabled(), "Assuming all spinlocks are without interrupts"); assert2(!are_interrupts_enabled(), "Assuming all spinlocks are without interrupts");
while (!try_lock()) { yield_self(); }// FIXME: Should be pause! while (!try_lock()) { yield_self(); } // FIXME: Should be pause!
} }
void unlock() { void unlock() {
@@ -44,7 +44,7 @@ public:
private: private:
std::atomic<bool> locked = false; std::atomic<bool> locked = false;
Task *owner; Task *owner;
}; };
static_assert(std::is_trivially_copyable_v<Spinlock> == true); static_assert(std::is_trivially_copyable_v<Spinlock> == true);
@@ -80,8 +80,8 @@ public:
SpinlockLockNoInt(SpinlockLockNoInt const &d) = delete; SpinlockLockNoInt(SpinlockLockNoInt const &d) = delete;
private: private:
Spinlock *lock; Spinlock *lock;
unsigned long f; unsigned long f;
}; };
#endif//OS2_SPINLOCK_H #endif //OS2_SPINLOCK_H

View File

@@ -9,10 +9,10 @@
#include "mutex.hpp" #include "mutex.hpp"
class Tty { class Tty {
public: public:
virtual void putchar(char c) = 0; virtual void putchar(char c) = 0;
virtual void putstr(const char *str) = 0; virtual void putstr(const char *str) = 0;
virtual char readchar() = 0; virtual char readchar() = 0;
}; };
#endif//OS2_TTY_HPP #endif //OS2_TTY_HPP

View File

@@ -8,11 +8,11 @@
#include "Vector.hpp" #include "Vector.hpp"
#include "mutex.hpp" #include "mutex.hpp"
TtyManager GlobalTtyManager; TtyManager GlobalTtyManager;
Vector<TtyManager> ttys; Vector<TtyManager> ttys;
void TtyManager::add_tty(Tty *tty) { void TtyManager::add_tty(Tty *tty) {
LockGuard l(lock); LockGuard l(lock);
ttys.emplace_back(tty); ttys.emplace_back(tty);
} }

View File

@@ -10,19 +10,19 @@
#include "Vector.hpp" #include "Vector.hpp"
class TtyManager { class TtyManager {
Mutex lock; Mutex lock;
Vector<Tty *> ttys; Vector<Tty *> ttys;
public: public:
void add_tty(Tty *tty); void add_tty(Tty *tty);
void all_tty_putchar(char c); void all_tty_putchar(char c);
void all_tty_putstr(const char *str); void all_tty_putstr(const char *str);
unsigned get_num_ttys(); unsigned get_num_ttys();
Tty *get_tty(unsigned n); Tty *get_tty(unsigned n);
}; };
extern TtyManager GlobalTtyManager; extern TtyManager GlobalTtyManager;
#endif//OS1_TTY_H #endif //OS1_TTY_H

View File

@@ -43,7 +43,7 @@ void *VMA::mmap_mem(void *v_addr, size_t length, int prot, int flags) {
length &= ~(PAGE_SIZE - 1); length &= ~(PAGE_SIZE - 1);
} }
assert((length & (PAGE_SIZE - 1)) == 0); assert((length & (PAGE_SIZE - 1)) == 0);
uint64_t page_len = length / PAGE_SIZE; uint64_t page_len = length / PAGE_SIZE;
std::optional<ListEntry> found; std::optional<ListEntry> found;
{ {

View File

@@ -21,24 +21,24 @@ public:
/// Map all higher-half pages into the address space /// Map all higher-half pages into the address space
/// By linking them to same entries as kernel /// By linking them to same entries as kernel
void map_kern(); void map_kern();
void *mmap_phys(void *v_addr, void *real_addr, size_t length, int flags); void *mmap_phys(void *v_addr, void *real_addr, size_t length, int flags);
void *mmap_mem(void *v_addr, size_t length, int prot, int flags); void *mmap_mem(void *v_addr, size_t length, int prot, int flags);
int munmap(void *addr, size_t length); int munmap(void *addr, size_t length);
private: private:
AddressSpace *space = nullptr; AddressSpace *space = nullptr;
Mutex space_lock; Mutex space_lock;
struct ListEntry { struct ListEntry {
uintptr_t begin; uintptr_t begin;
uint64_t length; uint64_t length;
bool available; bool available;
}; };
SkipList<uintptr_t, ListEntry> regions; SkipList<uintptr_t, ListEntry> regions;
Mutex regions_lock; Mutex regions_lock;
}; };
#endif//OS2_VMA_HPP #endif //OS2_VMA_HPP

View File

@@ -18,7 +18,7 @@ static inline void _assert2(int val, const char *msg) {
} }
#define assert2(x, y) _assert2(x, y) #define assert2(x, y) _assert2(x, y)
#define assert(x) _assert2(x, "Assertion failed") #define assert(x) _assert2(x, "Assertion failed")
#endif//OS2_ASSERTS_HPP #endif //OS2_ASSERTS_HPP

View File

@@ -15,7 +15,7 @@
#define STACK_CHK_GUARD 0x2e61e13e4d5ae23c #define STACK_CHK_GUARD 0x2e61e13e4d5ae23c
#endif #endif
uintptr_t __stack_chk_guard = STACK_CHK_GUARD; uintptr_t __stack_chk_guard = STACK_CHK_GUARD;
extern "C" __attribute__((noreturn)) void __stack_chk_fail(void) { extern "C" __attribute__((noreturn)) void __stack_chk_fail(void) {
assert2(false, "Stack protection triggered!"); assert2(false, "Stack protection triggered!");
@@ -32,11 +32,11 @@ namespace __cxxabiv1 {
/* The ABI requires a 64-bit type. */ /* The ABI requires a 64-bit type. */
__extension__ typedef int __guard __attribute__((mode(__DI__))); __extension__ typedef int __guard __attribute__((mode(__DI__)));
extern "C" int __cxa_guard_acquire(__guard *); extern "C" int __cxa_guard_acquire(__guard *);
extern "C" void __cxa_guard_release(__guard *); extern "C" void __cxa_guard_release(__guard *);
extern "C" void __cxa_guard_abort(__guard *); extern "C" void __cxa_guard_abort(__guard *);
extern "C" int __cxa_guard_acquire(__guard *g) { extern "C" int __cxa_guard_acquire(__guard *g) {
return !*(char *) (g); return !*(char *) (g);
} }
@@ -47,7 +47,7 @@ namespace __cxxabiv1 {
extern "C" void __cxa_guard_abort(__guard *) { extern "C" void __cxa_guard_abort(__guard *) {
_hcf(); _hcf();
} }
}// namespace __cxxabiv1 } // namespace __cxxabiv1
void *operator new(size_t size) { void *operator new(size_t size) {
return kmalloc(size); return kmalloc(size);

View File

@@ -18,7 +18,7 @@ struct Task;
// This is probably broken in some way // This is probably broken in some way
class CV { class CV {
List<Task *> waiters; List<Task *> waiters;
Spinlock waiters_lock; Spinlock waiters_lock;
public: public:
template<typename Lockable> template<typename Lockable>
@@ -55,4 +55,4 @@ public:
}; };
#endif//OS2_CV_HPP #endif //OS2_CV_HPP

View File

@@ -68,7 +68,7 @@ void Mutex::lock() {
void Mutex::unlock() { void Mutex::unlock() {
bool expected = true; bool expected = true;
_owner = nullptr; _owner = nullptr;
if (!locked.compare_exchange_strong(expected, false)) if (!locked.compare_exchange_strong(expected, false))
assert2(false, "Unlocking an unlocked mutex!\n"); assert2(false, "Unlocking an unlocked mutex!\n");
List<Task *>::Node *t = nullptr; List<Task *>::Node *t = nullptr;

View File

@@ -21,20 +21,20 @@ public:
void lock(); void lock();
// void spin_lock(); // void spin_lock();
bool try_lock(); bool try_lock();
void unlock(); void unlock();
bool test(); bool test();
Task *owner() { return _owner; } Task *owner() { return _owner; }
private: private:
std::atomic<bool> locked = false; std::atomic<bool> locked = false;
List<Task *> waiters; List<Task *> waiters;
Spinlock waiters_lock; Spinlock waiters_lock;
Task *_owner = nullptr; Task *_owner = nullptr;
uint8_t spin_success = 127; uint8_t spin_success = 127;
}; };
#endif//OS1_MUTEX_H #endif //OS1_MUTEX_H

View File

@@ -8,9 +8,9 @@
// The following functions define a portable implementation of rand and srand. // The following functions define a portable implementation of rand and srand.
static std::atomic<unsigned long int> next = 1;// NB: "unsigned long int" is assumed to be 32 bits wide static std::atomic<unsigned long int> next = 1; // NB: "unsigned long int" is assumed to be 32 bits wide
extern "C" int rand(void)// RAND_MAX assumed to be 32767 extern "C" int rand(void) // RAND_MAX assumed to be 32767
{ {
next = next * 1103515245 + 12345; next = next * 1103515245 + 12345;
return (unsigned int) (next / 65536ULL) % 32768; return (unsigned int) (next / 65536ULL) % 32768;

View File

@@ -11,11 +11,11 @@ extern "C" {
// The following functions define a portable implementation of rand and srand. // The following functions define a portable implementation of rand and srand.
#define RAND_MAX 32767 #define RAND_MAX 32767
int rand(void); int rand(void);
void srand(unsigned int seed); void srand(unsigned int seed);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif//OS2_RAND_H #endif //OS2_RAND_H

View File

@@ -13,8 +13,8 @@ extern "C" {
#include <stdint.h> #include <stdint.h>
inline void *memcpy(void *dest, const void *src, size_t n) { inline void *memcpy(void *dest, const void *src, size_t n) {
uint8_t *pdest = (uint8_t *) dest; uint8_t *pdest = (uint8_t *) dest;
const uint8_t *psrc = (const uint8_t *) src; const uint8_t *psrc = (const uint8_t *) src;
for (size_t i = 0; i < n; i++) { for (size_t i = 0; i < n; i++) {
pdest[i] = psrc[i]; pdest[i] = psrc[i];
@@ -34,8 +34,8 @@ inline void *memset(void *s, int c, size_t n) {
} }
inline void *memmove(void *dest, const void *src, size_t n) { inline void *memmove(void *dest, const void *src, size_t n) {
uint8_t *pdest = (uint8_t *) dest; uint8_t *pdest = (uint8_t *) dest;
const uint8_t *psrc = (const uint8_t *) src; const uint8_t *psrc = (const uint8_t *) src;
if (src > dest) { if (src > dest) {
for (size_t i = 0; i < n; i++) { for (size_t i = 0; i < n; i++) {
@@ -106,4 +106,4 @@ inline void strcpy(const char *src, char *dst) {
} }
#endif #endif
#endif//OS2_STRING_H #endif //OS2_STRING_H

View File

@@ -10,13 +10,13 @@
// FIXME // FIXME
template<typename T, auto S> template<typename T, auto S>
class CircularBuffer { class CircularBuffer {
T data[S]; T data[S];
int front, back; int front, back;
public: public:
CircularBuffer() { CircularBuffer() {
front = -1; front = -1;
back = -1; back = -1;
} }
bool full() { bool full() {
@@ -41,7 +41,7 @@ public:
assert(false); assert(false);
} else { } else {
if (front == -1) front = 0; if (front == -1) front = 0;
back = (back + 1) % S; back = (back + 1) % S;
data[back] = what; data[back] = what;
} }
} }
@@ -53,7 +53,7 @@ public:
T ret = data[front]; T ret = data[front];
if (front == back) { if (front == back) {
front = -1; front = -1;
back = -1; back = -1;
} else { } else {
front = (front + 1) % S; front = (front + 1) % S;
} }
@@ -62,4 +62,4 @@ public:
} }
}; };
#endif//OS2_CIRCULARBUFFER_HPP #endif //OS2_CIRCULARBUFFER_HPP

View File

@@ -15,14 +15,14 @@ template<typename T>
class List { class List {
public: public:
struct Node { struct Node {
T val; T val;
Node *next; Node *next;
List *list; List *list;
}; };
private: private:
Node *head = nullptr; Node *head = nullptr;
Node *tail = nullptr; Node *tail = nullptr;
uint64_t size = 0; uint64_t size = 0;
@@ -51,7 +51,7 @@ public:
assert(tail != nullptr); assert(tail != nullptr);
assert(size > 0); assert(size > 0);
head->next = new_node; head->next = new_node;
head = new_node; head = new_node;
} else { } else {
assert(size == 0); assert(size == 0);
head = new_node; head = new_node;
@@ -63,7 +63,7 @@ public:
bool empty() const { bool empty() const {
return tail == nullptr; return tail == nullptr;
} }
T &back() { T &back() {
if (tail != nullptr) { if (tail != nullptr) {
assert(size > 0); assert(size > 0);
@@ -99,7 +99,7 @@ public:
} }
auto old_tail = tail; auto old_tail = tail;
tail = tail->next; tail = tail->next;
delete old_tail; delete old_tail;
} }
@@ -113,15 +113,15 @@ public:
size--; size--;
if (tail == head) { if (tail == head) {
assert(size == 0); assert(size == 0);
auto b = tail; auto b = tail;
tail = nullptr; tail = nullptr;
head = nullptr; head = nullptr;
b->list = nullptr; b->list = nullptr;
return b; return b;
} }
auto old_tail = tail; auto old_tail = tail;
tail = tail->next; tail = tail->next;
old_tail->list = nullptr; old_tail->list = nullptr;
return old_tail; return old_tail;
} }
@@ -133,4 +133,4 @@ public:
}; };
#endif//OS2_LIST_HPP #endif //OS2_LIST_HPP

View File

@@ -22,18 +22,18 @@ public:
delete ptr; delete ptr;
} }
UniquePtr(UniquePtr const &other) = delete; UniquePtr(UniquePtr const &other) = delete;
UniquePtr &operator=(UniquePtr const &other) = delete; UniquePtr &operator=(UniquePtr const &other) = delete;
UniquePtr(UniquePtr &&other) { UniquePtr(UniquePtr &&other) {
delete ptr; delete ptr;
ptr = other.ptr; ptr = other.ptr;
other.ptr = nullptr; other.ptr = nullptr;
} }
UniquePtr &operator=(UniquePtr &&other) { UniquePtr &operator=(UniquePtr &&other) {
delete ptr; delete ptr;
ptr = other.ptr; ptr = other.ptr;
other.ptr = nullptr; other.ptr = nullptr;
return *this; return *this;
} }
@@ -46,7 +46,7 @@ public:
T *release() noexcept { T *release() noexcept {
auto b = ptr; auto b = ptr;
ptr = nullptr; ptr = nullptr;
return b; return b;
} }
@@ -77,10 +77,10 @@ public:
} }
SharedPtr(SharedPtr &&other) { SharedPtr(SharedPtr &&other) {
uses = other.uses; uses = other.uses;
ptr = other.ptr; ptr = other.ptr;
other.uses = nullptr; other.uses = nullptr;
other.ptr = nullptr; other.ptr = nullptr;
} }
SharedPtr &operator=(SharedPtr other) { SharedPtr &operator=(SharedPtr other) {
@@ -89,16 +89,16 @@ public:
return *this; return *this;
} }
T *operator->() const { return ptr; } T *operator->() const { return ptr; }
T &operator*() const { return *ptr; } T &operator*() const { return *ptr; }
T *get() const noexcept { return ptr; } T *get() const noexcept { return ptr; }
[[nodiscard]] int useCount() const { return *uses; } [[nodiscard]] int useCount() const { return *uses; }
private: private:
T *ptr = nullptr; T *ptr = nullptr;
int *uses = nullptr; int *uses = nullptr;
}; };
@@ -110,7 +110,7 @@ private:
friend COWTester; friend COWTester;
SharedPtr<T> ptr; SharedPtr<T> ptr;
void copy() { void copy() {
if (ptr.get() && ptr.useCount() > 1) { if (ptr.get() && ptr.useCount() > 1) {
ptr = SharedPtr<T>(new T(*ptr)); ptr = SharedPtr<T>(new T(*ptr));
} }
@@ -123,7 +123,7 @@ public:
explicit COWPointer(SharedPtr<T> data) : ptr(std::move(data)) {} explicit COWPointer(SharedPtr<T> data) : ptr(std::move(data)) {}
COWPointer(COWPointer &&other) = default; COWPointer(COWPointer &&other) = default;
COWPointer(COWPointer const &data) = default; COWPointer(COWPointer const &data) = default;
@@ -143,7 +143,7 @@ public:
return ptr.get(); return ptr.get();
} }
int useCount() { return ptr.useCount(); }; int useCount() { return ptr.useCount(); };
const T &operator*() const { const T &operator*() const {
return *ptr; return *ptr;

View File

@@ -16,18 +16,18 @@ class SkipList {
public: public:
struct Node { struct Node {
Node *next[maxL + 1] = {nullptr}; Node *next[maxL + 1] = {nullptr};
Node *before = nullptr; Node *before = nullptr;
bool end = false; bool end = false;
K key = K(); K key = K();
V data = V(); V data = V();
}; };
private: private:
class NodeAllocator { class NodeAllocator {
static constexpr int size{64}; static constexpr int size{64};
Node *nodes[size]; Node *nodes[size];
int top = -1; int top = -1;
public: public:
NodeAllocator() noexcept = default; NodeAllocator() noexcept = default;
@@ -52,12 +52,12 @@ private:
return new Node; return new Node;
} }
Node *node = nodes[top--]; Node *node = nodes[top--];
node->end = false; node->end = false;
node->before = nullptr; node->before = nullptr;
node->next[0] = nullptr; node->next[0] = nullptr;
node->key = K(); node->key = K();
// node->data = V(); // node->data = V();
return node; return node;
@@ -67,23 +67,23 @@ private:
static int randomL() { static int randomL() {
int ret = __builtin_ffs(rand()); int ret = __builtin_ffs(rand());
assert(ret >= 0); assert(ret >= 0);
return ret;// NOLINT return ret; // NOLINT
} }
// static inline NodeAllocator nodeAllocator; // static inline NodeAllocator nodeAllocator;
NodeAllocator nodeAllocator; NodeAllocator nodeAllocator;
Node *root; Node *root;
Node *endnode; Node *endnode;
mutable Node *toUpdate[maxL + 1]; mutable Node *toUpdate[maxL + 1];
size_t curL = 0; size_t curL = 0;
public: public:
SkipList() noexcept { SkipList() noexcept {
root = (Node *) nodeAllocator.get(); root = (Node *) nodeAllocator.get();
root->end = true; root->end = true;
endnode = (Node *) nodeAllocator.get(); endnode = (Node *) nodeAllocator.get();
endnode->end = true; endnode->end = true;
endnode->before = root; endnode->before = root;
for (size_t i = 0; i <= maxL; i++) { for (size_t i = 0; i <= maxL; i++) {
@@ -95,7 +95,7 @@ public:
auto cur = root; auto cur = root;
while (cur != nullptr) { while (cur != nullptr) {
auto prev = cur; auto prev = cur;
cur = cur->next[0]; cur = cur->next[0];
nodeAllocator.push(prev); nodeAllocator.push(prev);
} }
} }
@@ -112,27 +112,27 @@ public:
curL = newLevel; curL = newLevel;
} }
auto newNode = (Node *) nodeAllocator.get(); auto newNode = (Node *) nodeAllocator.get();
newNode->key = n->key; newNode->key = n->key;
newNode->data = n->data; newNode->data = n->data;
newNode->before = toUpdate[0]; newNode->before = toUpdate[0];
if (toUpdate[0]->next[0] != nullptr) toUpdate[0]->next[0]->before = newNode; if (toUpdate[0]->next[0] != nullptr) toUpdate[0]->next[0]->before = newNode;
for (size_t i = 0; i <= newLevel; i++) { for (size_t i = 0; i <= newLevel; i++) {
newNode->next[i] = toUpdate[i]->next[i]; newNode->next[i] = toUpdate[i]->next[i];
toUpdate[i]->next[i] = newNode; toUpdate[i]->next[i] = newNode;
toUpdate[i] = newNode; toUpdate[i] = newNode;
} }
} }
} }
SkipList(SkipList &&l) noexcept { SkipList(SkipList &&l) noexcept {
this->root = l.root; this->root = l.root;
l.root = nullptr; l.root = nullptr;
this->endnode = l.endnode; this->endnode = l.endnode;
l.endnode = nullptr; l.endnode = nullptr;
this->curL = l.curL; this->curL = l.curL;
l.curL = 0; l.curL = 0;
} }
SkipList &operator=(SkipList l) noexcept { SkipList &operator=(SkipList l) noexcept {
@@ -237,17 +237,17 @@ public:
curL = newLevel; curL = newLevel;
} }
auto newNode = (Node *) nodeAllocator.get(); auto newNode = (Node *) nodeAllocator.get();
newNode->key = k; newNode->key = k;
newNode->data = std::move(v); newNode->data = std::move(v);
newNode->before = toUpdate[0]; newNode->before = toUpdate[0];
if (toUpdate[0]->next[0] != nullptr) toUpdate[0]->next[0]->before = newNode; if (toUpdate[0]->next[0] != nullptr) toUpdate[0]->next[0]->before = newNode;
for (size_t i = 0; i <= newLevel; i++) { for (size_t i = 0; i <= newLevel; i++) {
newNode->next[i] = toUpdate[i]->next[i]; newNode->next[i] = toUpdate[i]->next[i];
toUpdate[i]->next[i] = newNode; toUpdate[i]->next[i] = newNode;
toUpdate[i] = newNode; toUpdate[i] = newNode;
} }
return newNode; return newNode;
} }
@@ -336,12 +336,12 @@ public:
bool operator==(SkipList const &r) const { bool operator==(SkipList const &r) const {
auto n = root->next[0]; auto n = root->next[0];
auto n2 = r.root->next[0]; auto n2 = r.root->next[0];
while (!n->end && !n2->end) { while (!n->end && !n2->end) {
if (!(n->data == n2->data)) return false; if (!(n->data == n2->data)) return false;
n = n->next[0]; n = n->next[0];
n2 = n2->next[0]; n2 = n2->next[0];
} }
@@ -355,15 +355,15 @@ public:
struct SkipListIterator { struct SkipListIterator {
// using iterator_category = std::forward_iterator_tag; // using iterator_category = std::forward_iterator_tag;
using difference_type = std::ptrdiff_t; using difference_type = std::ptrdiff_t;
using value_type = Node; using value_type = Node;
using pointer = value_type *; using pointer = value_type *;
using reference = value_type &; using reference = value_type &;
explicit SkipListIterator(Node *n) : n(std::move(n)){}; explicit SkipListIterator(Node *n) : n(std::move(n)){};
reference operator*() const { return *n; } reference operator*() const { return *n; }
pointer operator->() const { return n; } pointer operator->() const { return n; }
SkipListIterator &operator--() { SkipListIterator &operator--() {
if (!n->end) if (!n->end)

View File

@@ -8,16 +8,16 @@ class SkipListSet {
public: public:
struct Node { struct Node {
Node *next[maxL + 1] = {nullptr}; Node *next[maxL + 1] = {nullptr};
Node *before = nullptr; Node *before = nullptr;
bool end = false; bool end = false;
K key = K(); K key = K();
}; };
private: private:
class NodeAllocator { class NodeAllocator {
static constexpr int size{64}; static constexpr int size{64};
Node *nodes[size]; Node *nodes[size];
int top = -1; int top = -1;
public: public:
NodeAllocator() noexcept = default; NodeAllocator() noexcept = default;
@@ -42,12 +42,12 @@ private:
return new Node; return new Node;
} }
Node *node = nodes[top--]; Node *node = nodes[top--];
node->end = false; node->end = false;
node->before = nullptr; node->before = nullptr;
node->next[0] = nullptr; node->next[0] = nullptr;
node->key = K(); node->key = K();
// node->data = V(); // node->data = V();
return node; return node;
@@ -57,22 +57,22 @@ private:
static int randomL() { static int randomL() {
int ret = __builtin_ffs(rand()); int ret = __builtin_ffs(rand());
assert(ret >= 0); assert(ret >= 0);
return ret;// NOLINT return ret; // NOLINT
} }
NodeAllocator nodeAllocator; NodeAllocator nodeAllocator;
Node *root; Node *root;
Node *endnode; Node *endnode;
mutable Node *toUpdate[maxL + 1]; mutable Node *toUpdate[maxL + 1];
size_t curL = 0; size_t curL = 0;
public: public:
SkipListSet() noexcept { SkipListSet() noexcept {
root = (Node *) nodeAllocator.get(); root = (Node *) nodeAllocator.get();
root->end = true; root->end = true;
endnode = (Node *) nodeAllocator.get(); endnode = (Node *) nodeAllocator.get();
endnode->end = true; endnode->end = true;
endnode->before = root; endnode->before = root;
for (size_t i = 0; i <= maxL; i++) { for (size_t i = 0; i <= maxL; i++) {
@@ -84,7 +84,7 @@ public:
auto cur = root; auto cur = root;
while (cur != nullptr) { while (cur != nullptr) {
auto prev = cur; auto prev = cur;
cur = cur->next[0]; cur = cur->next[0];
nodeAllocator.push(prev); nodeAllocator.push(prev);
} }
} }
@@ -101,27 +101,27 @@ public:
curL = newLevel; curL = newLevel;
} }
auto newNode = (Node *) nodeAllocator.get(); auto newNode = (Node *) nodeAllocator.get();
newNode->key = n->key; newNode->key = n->key;
newNode->data = n->data; newNode->data = n->data;
newNode->before = toUpdate[0]; newNode->before = toUpdate[0];
if (toUpdate[0]->next[0] != nullptr) toUpdate[0]->next[0]->before = newNode; if (toUpdate[0]->next[0] != nullptr) toUpdate[0]->next[0]->before = newNode;
for (size_t i = 0; i <= newLevel; i++) { for (size_t i = 0; i <= newLevel; i++) {
newNode->next[i] = toUpdate[i]->next[i]; newNode->next[i] = toUpdate[i]->next[i];
toUpdate[i]->next[i] = newNode; toUpdate[i]->next[i] = newNode;
toUpdate[i] = newNode; toUpdate[i] = newNode;
} }
} }
} }
SkipListSet(SkipListSet &&l) noexcept { SkipListSet(SkipListSet &&l) noexcept {
this->root = l.root; this->root = l.root;
l.root = nullptr; l.root = nullptr;
this->endnode = l.endnode; this->endnode = l.endnode;
l.endnode = nullptr; l.endnode = nullptr;
this->curL = l.curL; this->curL = l.curL;
l.curL = 0; l.curL = 0;
} }
SkipListSet &operator=(SkipListSet l) noexcept { SkipListSet &operator=(SkipListSet l) noexcept {
@@ -191,16 +191,16 @@ public:
curL = newLevel; curL = newLevel;
} }
auto newNode = (Node *) nodeAllocator.get(); auto newNode = (Node *) nodeAllocator.get();
newNode->key = k; newNode->key = k;
newNode->before = toUpdate[0]; newNode->before = toUpdate[0];
if (toUpdate[0]->next[0] != nullptr) toUpdate[0]->next[0]->before = newNode; if (toUpdate[0]->next[0] != nullptr) toUpdate[0]->next[0]->before = newNode;
for (size_t i = 0; i <= newLevel; i++) { for (size_t i = 0; i <= newLevel; i++) {
newNode->next[i] = toUpdate[i]->next[i]; newNode->next[i] = toUpdate[i]->next[i];
toUpdate[i]->next[i] = newNode; toUpdate[i]->next[i] = newNode;
toUpdate[i] = newNode; toUpdate[i] = newNode;
} }
return newNode; return newNode;
} }
@@ -288,12 +288,12 @@ public:
bool operator==(SkipListSet const &r) const { bool operator==(SkipListSet const &r) const {
auto n = root->next[0]; auto n = root->next[0];
auto n2 = r.root->next[0]; auto n2 = r.root->next[0];
while (!n->end && !n2->end) { while (!n->end && !n2->end) {
if (!(n->data == n2->data)) return false; if (!(n->data == n2->data)) return false;
n = n->next[0]; n = n->next[0];
n2 = n2->next[0]; n2 = n2->next[0];
} }

View File

@@ -11,35 +11,35 @@
class String { class String {
public: public:
String() noexcept { String() noexcept {
_data = static_cast<char *>(kmalloc(1 * sizeof(char))); _data = static_cast<char *>(kmalloc(1 * sizeof(char)));
curLen = 0; curLen = 0;
_data[0] = '\0'; _data[0] = '\0';
} }
String(const char *in) noexcept { String(const char *in) noexcept {
curLen = strlen(in); curLen = strlen(in);
_data = static_cast<char *>(kmalloc((curLen + 1) * sizeof(char))); _data = static_cast<char *>(kmalloc((curLen + 1) * sizeof(char)));
_data[0] = '\0'; _data[0] = '\0';
strcat(_data, in); strcat(_data, in);
} }
String(String const &str) noexcept { String(String const &str) noexcept {
curLen = str.curLen; curLen = str.curLen;
_data = static_cast<char *>(kmalloc((curLen + 1) * sizeof(char))); _data = static_cast<char *>(kmalloc((curLen + 1) * sizeof(char)));
_data[0] = '\0'; _data[0] = '\0';
strcat(_data, str._data); strcat(_data, str._data);
} }
String(String &&str) noexcept { String(String &&str) noexcept {
_data = str._data; _data = str._data;
curLen = str.curLen; curLen = str.curLen;
str._data = static_cast<char *>(kmalloc(1 * sizeof(char))); str._data = static_cast<char *>(kmalloc(1 * sizeof(char)));
str.curLen = 0; str.curLen = 0;
str._data[0] = '\0'; str._data[0] = '\0';
} }
@@ -52,7 +52,7 @@ public:
~String() noexcept { ~String() noexcept {
if (_data == nullptr) return; if (_data == nullptr) return;
kfree(_data); kfree(_data);
_data = nullptr; _data = nullptr;
curLen = 0; curLen = 0;
} }
@@ -87,7 +87,7 @@ public:
_data = static_cast<char *>(krealloc(_data, sizeof(char) * (curLen + 2))); _data = static_cast<char *>(krealloc(_data, sizeof(char) * (curLen + 2)));
assert(_data != nullptr); assert(_data != nullptr);
_data[curLen] = c; _data[curLen] = c;
_data[curLen + 1] = '\0'; _data[curLen + 1] = '\0';
curLen++; curLen++;
return *this; return *this;
@@ -96,7 +96,7 @@ public:
const char *c_str() const { const char *c_str() const {
return _data; return _data;
} }
char *data() { char *data() {
return _data; return _data;
} }
@@ -131,7 +131,7 @@ public:
private: private:
size_t curLen = 0; size_t curLen = 0;
char *_data; char *_data;
}; };
#endif #endif

View File

@@ -7,4 +7,4 @@
int test_templates(); int test_templates();
#endif//OS2_TESTTEMPLATES_HPP #endif //OS2_TESTTEMPLATES_HPP

View File

@@ -19,10 +19,10 @@ public:
} }
Vector(std::initializer_list<T> l) noexcept { Vector(std::initializer_list<T> l) noexcept {
curSize = l.size(); curSize = l.size();
capacity = curSize > 0 ? curSize : 2; capacity = curSize > 0 ? curSize : 2;
data = static_cast<T *>(kmalloc(capacity * sizeof(T))); data = static_cast<T *>(kmalloc(capacity * sizeof(T)));
size_t i = 0; size_t i = 0;
for (auto const &el: l) { for (auto const &el: l) {
@@ -31,20 +31,20 @@ public:
} }
Vector(Vector const &vec) noexcept { Vector(Vector const &vec) noexcept {
curSize = vec.curSize; curSize = vec.curSize;
capacity = curSize > 0 ? curSize : 2; capacity = curSize > 0 ? curSize : 2;
data = static_cast<T *>(kmalloc(capacity * sizeof(T))); data = static_cast<T *>(kmalloc(capacity * sizeof(T)));
for (size_t i = 0; i < curSize; i++) for (size_t i = 0; i < curSize; i++)
new (data + i) T(vec.data[i]); new (data + i) T(vec.data[i]);
} }
Vector(Vector &&v) noexcept { Vector(Vector &&v) noexcept {
curSize = v.curSize; curSize = v.curSize;
capacity = v.capacity; capacity = v.capacity;
data = v.data; data = v.data;
v.data = nullptr; v.data = nullptr;
} }
Vector &operator=(Vector vec) noexcept { Vector &operator=(Vector vec) noexcept {
@@ -74,7 +74,7 @@ public:
} }
void compact() { void compact() {
data = (T *) krealloc(reinterpret_cast<char *>(data), curSize * sizeof(T)); data = (T *) krealloc(reinterpret_cast<char *>(data), curSize * sizeof(T));
capacity = curSize; capacity = curSize;
} }
@@ -141,8 +141,8 @@ public:
private: private:
size_t capacity = 2; size_t capacity = 2;
size_t curSize = 0; size_t curSize = 0;
T *data; T *data;
}; };
#endif #endif

View File

@@ -15,30 +15,30 @@
class FDT { class FDT {
public: public:
using FD = int64_t; using FD = int64_t;
FD open(const Path &p, FileOpts opts); FD open(const Path &p, FileOpts opts);
void close(FD fd); void close(FD fd);
File *get(FD fd) const; File *get(FD fd) const;
static FDT *current(); static FDT *current();
private: private:
SkipList<FD, UniquePtr<File>> _files; SkipList<FD, UniquePtr<File>> _files;
int64_t _cur_fd = 10; int64_t _cur_fd = 10;
mutable Mutex _mtx; mutable Mutex _mtx;
}; };
class FDHandle { class FDHandle {
public: public:
FDHandle(FDT::FD fd); FDHandle(FDT::FD fd);
~FDHandle(); ~FDHandle();
FDHandle(const File &f) = delete; FDHandle(const File &f) = delete;
FDHandle &operator=(const File &o) = delete; FDHandle &operator=(const File &o) = delete;
FDT::FD get() { return _fd; } FDT::FD get() { return _fd; }
private: private:
FDT::FD _fd; FDT::FD _fd;
}; };
#endif//OS2_FDT_HPP #endif //OS2_FDT_HPP

View File

@@ -16,22 +16,22 @@ class File {
public: public:
File(Node *n, FileOpts opts); File(Node *n, FileOpts opts);
~File(); ~File();
File(const File &f) = delete; File(const File &f) = delete;
File &operator=(const File &o) = delete; File &operator=(const File &o) = delete;
Node *node(); Node *node();
NodeDir *dir(); NodeDir *dir();
NodeFile *file() const; NodeFile *file() const;
uint64_t seek(uint64_t pos); uint64_t seek(uint64_t pos);
uint64_t read(char *buf, uint64_t size); uint64_t read(char *buf, uint64_t size);
uint64_t write(const char *buf, uint64_t size); uint64_t write(const char *buf, uint64_t size);
uint64_t size(); uint64_t size();
private: private:
Node *const _n; Node *const _n;
uint64_t _pos = 0; uint64_t _pos = 0;
FileOpts _opts; FileOpts _opts;
}; };
#endif//OS2_FILE_HPP #endif //OS2_FILE_HPP

View File

@@ -12,10 +12,10 @@ public:
Filesystem(NodeDir *mounted_on); Filesystem(NodeDir *mounted_on);
virtual NodeDir *root() = 0; virtual NodeDir *root() = 0;
virtual ~Filesystem() = 0; virtual ~Filesystem() = 0;
NodeDir *_mounted_on; NodeDir *_mounted_on;
}; };
#endif//OS2_FILESYSTEM_HPP #endif //OS2_FILESYSTEM_HPP

View File

@@ -6,7 +6,7 @@
#include "LockGuard.hpp" #include "LockGuard.hpp"
Vector<Node *> MemFs::MemFsNodeDir::children() { Vector<Node *> MemFs::MemFsNodeDir::children() {
LockGuard l(_lock); LockGuard l(_lock);
Vector<Node *> out; Vector<Node *> out;
for (auto c: _children) { for (auto c: _children) {
@@ -17,14 +17,14 @@ Vector<Node *> MemFs::MemFsNodeDir::children() {
NodeDir *MemFs::MemFsNodeDir::mkdir(const String &name) { NodeDir *MemFs::MemFsNodeDir::mkdir(const String &name) {
LockGuard l(_lock); LockGuard l(_lock);
auto newnode = new MemFsNodeDir(); auto newnode = new MemFsNodeDir();
newnode->_name = name; newnode->_name = name;
_children.add(name, newnode); _children.add(name, newnode);
return newnode; return newnode;
} }
NodeFile *MemFs::MemFsNodeDir::mkfile(const String &name) { NodeFile *MemFs::MemFsNodeDir::mkfile(const String &name) {
LockGuard l(_lock); LockGuard l(_lock);
auto newfile = new MemFsNodeFile(name); auto newfile = new MemFsNodeFile(name);
_children.add(name, newfile); _children.add(name, newfile);
return newfile; return newfile;
} }

View File

@@ -15,8 +15,8 @@ class MemFs : public Filesystem {
struct MemFsNodeDir : public NodeDir { struct MemFsNodeDir : public NodeDir {
public: public:
Vector<Node *> children() override; Vector<Node *> children() override;
NodeDir *mkdir(const String &name) override; NodeDir *mkdir(const String &name) override;
NodeFile *mkfile(const String &name) override; NodeFile *mkfile(const String &name) override;
private: private:
SkipList<String, Node *> _children; SkipList<String, Node *> _children;
@@ -26,8 +26,8 @@ class MemFs : public Filesystem {
public: public:
MemFsNodeFile(const String &name) { _name = name; } MemFsNodeFile(const String &name) { _name = name; }
bool read(char *buf, size_t start, size_t num) override; bool read(char *buf, size_t start, size_t num) override;
bool write(const char *buf, size_t start, size_t num) override; bool write(const char *buf, size_t start, size_t num) override;
size_t size() override; size_t size() override;
private: private:
@@ -44,4 +44,4 @@ private:
}; };
#endif//OS2_MEMFS_HPP #endif //OS2_MEMFS_HPP

View File

@@ -20,4 +20,4 @@ private:
}; };
#endif//OS2_MOUNTTABLE_HPP #endif //OS2_MOUNTTABLE_HPP

View File

@@ -9,8 +9,8 @@
Node::~Node() = default; Node::~Node() = default;
Node *Node::traverse(const Path &path) { Node *Node::traverse(const Path &path) {
NodeDir &nodeDir = static_cast<NodeDir &>(*this); NodeDir &nodeDir = static_cast<NodeDir &>(*this);
Filesystem *mnt; Filesystem *mnt;
{ {
LockGuard l(_lock); LockGuard l(_lock);

View File

@@ -23,7 +23,7 @@ public:
}; };
virtual ~Node() = 0; virtual ~Node() = 0;
Type type() const { return _type; } Type type() const { return _type; }
const String &name() const { const String &name() const {
LockGuard l(_lock); LockGuard l(_lock);
return _name; return _name;
@@ -38,18 +38,18 @@ protected:
// This is uuugly // This is uuugly
mutable Mutex _lock; mutable Mutex _lock;
String _name; String _name;
Filesystem *_mount = nullptr; Filesystem *_mount = nullptr;
}; };
class NodeFile; class NodeFile;
class NodeDir : public Node { class NodeDir : public Node {
public: public:
virtual Vector<Node *> children() = 0; virtual Vector<Node *> children() = 0;
virtual NodeDir *mkdir(const String &name) = 0; virtual NodeDir *mkdir(const String &name) = 0;
virtual NodeFile *mkfile(const String &name) = 0; virtual NodeFile *mkfile(const String &name) = 0;
virtual void set_mounted(Filesystem *mount); virtual void set_mounted(Filesystem *mount);
protected: protected:
NodeDir() : Node(Type::DIR) {} NodeDir() : Node(Type::DIR) {}
@@ -57,13 +57,13 @@ protected:
class NodeFile : public Node { class NodeFile : public Node {
public: public:
virtual bool read(char *buf, size_t start, size_t num) = 0; virtual bool read(char *buf, size_t start, size_t num) = 0;
virtual bool write(const char *buf, size_t start, size_t num) = 0; virtual bool write(const char *buf, size_t start, size_t num) = 0;
virtual size_t size() = 0; virtual size_t size() = 0;
protected: protected:
NodeFile() : Node(Type::FILE) {} NodeFile() : Node(Type::FILE) {}
}; };
#endif//OS2_NODE_HPP #endif //OS2_NODE_HPP

View File

@@ -5,7 +5,7 @@
#include "Path.hpp" #include "Path.hpp"
Path StrToPath(const String &str) { Path StrToPath(const String &str) {
if (str.length() == 0) return Path(); if (str.length() == 0) return Path();
Path out; Path out;
String buf; String buf;
for (size_t i = 0; i < str.length(); i++) { for (size_t i = 0; i < str.length(); i++) {
if (str.c_str()[i] == '/') { if (str.c_str()[i] == '/') {

View File

@@ -13,4 +13,4 @@ using Path = Vector<String>;
Path StrToPath(const String &str); Path StrToPath(const String &str);
#endif//OS2_PATH_HPP #endif //OS2_PATH_HPP

View File

@@ -8,7 +8,7 @@
#include "Node.hpp" #include "Node.hpp"
bool VFSApi::mkdir(const Path &path) { bool VFSApi::mkdir(const Path &path) {
auto root = path.subvector(0, path.size() - 1); auto root = path.subvector(0, path.size() - 1);
FDHandle root_fd = FDHandle(FDT::current()->open(root, O_RDWR)); FDHandle root_fd = FDHandle(FDT::current()->open(root, O_RDWR));
if (root_fd.get() == -1) return false; if (root_fd.get() == -1) return false;
File *root_f = FDT::current()->get(root_fd.get()); File *root_f = FDT::current()->get(root_fd.get());
@@ -17,7 +17,7 @@ bool VFSApi::mkdir(const Path &path) {
return true; return true;
} }
bool VFSApi::touch(const Path &path) { bool VFSApi::touch(const Path &path) {
auto root = path.subvector(0, path.size() - 1); auto root = path.subvector(0, path.size() - 1);
FDHandle root_fd = FDHandle(FDT::current()->open(root, O_RDWR)); FDHandle root_fd = FDHandle(FDT::current()->open(root, O_RDWR));
if (root_fd.get() == -1) return false; if (root_fd.get() == -1) return false;
File *root_f = FDT::current()->get(root_fd.get()); File *root_f = FDT::current()->get(root_fd.get());

View File

@@ -10,14 +10,14 @@
#include "Path.hpp" #include "Path.hpp"
namespace VFSApi { namespace VFSApi {
bool mkdir(const Path &path); bool mkdir(const Path &path);
bool touch(const Path &path); bool touch(const Path &path);
FDT::FD open(const Path &path); FDT::FD open(const Path &path);
File *get(FDT::FD fd); File *get(FDT::FD fd);
void close(FDT::FD fd); void close(FDT::FD fd);
};// namespace VFSApi }; // namespace VFSApi
#endif//OS2_VFSAPI_HPP #endif //OS2_VFSAPI_HPP

View File

@@ -17,5 +17,5 @@ NodeFile *RootNode::mkfile(const String &name) {
} }
RootNode VFSGlobals::root; RootNode VFSGlobals::root;
MountTable VFSGlobals::mounts; MountTable VFSGlobals::mounts;

View File

@@ -11,14 +11,14 @@
class RootNode : public NodeDir { class RootNode : public NodeDir {
public: public:
Vector<Node *> children() override; Vector<Node *> children() override;
NodeDir *mkdir(const String &name) override; NodeDir *mkdir(const String &name) override;
NodeFile *mkfile(const String &name) override; NodeFile *mkfile(const String &name) override;
}; };
namespace VFSGlobals { namespace VFSGlobals {
extern RootNode root; extern RootNode root;
extern MountTable mounts; extern MountTable mounts;
};// namespace VFSGlobals }; // namespace VFSGlobals
#endif//OS2_VFSGLOBALS_HPP #endif //OS2_VFSGLOBALS_HPP

View File

@@ -19,7 +19,7 @@ void VFSTester::test() {
FDT::FD d = VFSApi::open(StrToPath("/hello/f2")); FDT::FD d = VFSApi::open(StrToPath("/hello/f2"));
{ {
String t("hello wooooorld"); String t("hello wooooorld");
File *cf = VFSApi::get(c); File *cf = VFSApi::get(c);
cf->write(t.c_str(), t.length() + 1); cf->write(t.c_str(), t.length() + 1);
} }
assert(a != -1); assert(a != -1);
@@ -35,13 +35,13 @@ void VFSTester::test() {
assert(c != -1); assert(c != -1);
{ {
String t("aaaaaaaaaaaaaaaaaaaa"); String t("aaaaaaaaaaaaaaaaaaaa");
File *cf = VFSApi::get(c); File *cf = VFSApi::get(c);
cf->read(t.data(), cf->size()); cf->read(t.data(), cf->size());
assert(t == "hello wooooorld"); assert(t == "hello wooooorld");
} }
{ {
String t("aaaaaaaaaaaaaaaaaaaa"); String t("aaaaaaaaaaaaaaaaaaaa");
File *cf = VFSApi::get(c); File *cf = VFSApi::get(c);
cf->seek(0); cf->seek(0);
cf->read(t.data(), 9); cf->read(t.data(), 9);
cf->read(t.data() + 9, cf->size() - 9); cf->read(t.data() + 9, cf->size() - 9);

View File

@@ -12,4 +12,4 @@ public:
}; };
#endif//OS2_VFSTESTER_HPP #endif //OS2_VFSTESTER_HPP

View File

@@ -5,7 +5,7 @@ void _start() {
// putchar('h'); // putchar('h');
// putchar('i'); // putchar('i');
// putchar('\n'); // putchar('\n');
uint64_t test123 = open("/test123", O_CREAT | O_RDWR); uint64_t test123 = open("/test123", O_CREAT | O_RDWR);
const char *teststr = "test str"; const char *teststr = "test str";
write(test123, teststr, 9); write(test123, teststr, 9);
close(test123); close(test123);

View File

@@ -13,10 +13,10 @@ extern "C" {
#endif #endif
enum FileOpts : uint8_t { enum FileOpts : uint8_t {
O_RDONLY = 1 << 1,// Read O_RDONLY = 1 << 1, // Read
O_WRONLY = 1 << 2,// Write O_WRONLY = 1 << 2, // Write
O_RDWR = O_RDONLY | O_WRONLY, O_RDWR = O_RDONLY | O_WRONLY,
O_CREAT = 1 << 3,// Create O_CREAT = 1 << 3, // Create
}; };
#ifdef __cplusplus #ifdef __cplusplus
@@ -24,4 +24,4 @@ enum FileOpts : uint8_t {
#endif #endif
#endif//OS2_FILEOPTS_HPP #endif //OS2_FILEOPTS_HPP

View File

@@ -15,7 +15,7 @@ extern "C" {
struct dirent { struct dirent {
uint64_t inode_n; uint64_t inode_n;
char d_name[]; char d_name[];
}; };
#ifdef __cplusplus #ifdef __cplusplus
@@ -23,4 +23,4 @@ struct dirent {
#endif #endif
#endif//OS2_DIRENT_H #endif //OS2_DIRENT_H

View File

@@ -14,25 +14,25 @@ extern "C" {
#include "FileOpts.h" #include "FileOpts.h"
#define SYSCALL_PUTCHAR_ID 1 #define SYSCALL_PUTCHAR_ID 1
#define SYSCALL_SLEEP_ID 2 #define SYSCALL_SLEEP_ID 2
#define SYSCALL_READCHAR_ID 3 #define SYSCALL_READCHAR_ID 3
#define SYSCALL_OPEN_ID 4 #define SYSCALL_OPEN_ID 4
#define SYSCALL_CLOSE_ID 5 #define SYSCALL_CLOSE_ID 5
#define SYSCALL_READ_ID 6 #define SYSCALL_READ_ID 6
#define SYSCALL_WRITE_ID 7 #define SYSCALL_WRITE_ID 7
#define SYSCALL_LSEEK_ID 8 #define SYSCALL_LSEEK_ID 8
#define SYSCALL_OPENDIR_ID 9 #define SYSCALL_OPENDIR_ID 9
#define SYSCALL_READDIR_ID 10 #define SYSCALL_READDIR_ID 10
#define SYSCALL_CLOSEDIR_ID 11 #define SYSCALL_CLOSEDIR_ID 11
#define SYSCALL_MKDIR_ID 12 #define SYSCALL_MKDIR_ID 12
#define SYSCALL_UNLINK_ID 13 #define SYSCALL_UNLINK_ID 13
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif//OS2_SYSCALLS_DEFS_H #endif //OS2_SYSCALLS_DEFS_H

View File

@@ -8,7 +8,7 @@
uint64_t do_syscall(uint64_t id_rdi, uint64_t a1_rsi, uint64_t a2_rdx, uint64_t a3_rcx) { uint64_t do_syscall(uint64_t id_rdi, uint64_t a1_rsi, uint64_t a2_rdx, uint64_t a3_rcx) {
uint64_t res; uint64_t res;
asm volatile("syscall; mov (0x10016), %%rsp"// TASK_POINTER->ret_sp_val asm volatile("syscall; mov (0x10016), %%rsp" // TASK_POINTER->ret_sp_val
: "=r"(res) : "=r"(res)
: "D"(id_rdi), "S"(a1_rsi), "d"(a2_rdx), "a"(a3_rcx) : "D"(id_rdi), "S"(a1_rsi), "d"(a2_rdx), "a"(a3_rcx)
: "cc", "rcx", "r8", : "cc", "rcx", "r8",

View File

@@ -31,4 +31,4 @@ uint64_t lseek(uint64_t fd, uint64_t off, uint64_t whence);
} }
#endif #endif
#endif//OS2_SYSCALLS_INTERFACE_H #endif //OS2_SYSCALLS_INTERFACE_H