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
AccessModifierOffset: -4
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
AlignEscapedNewlines: Right
AllowAllArgumentsOnNextLine: false
@@ -57,7 +76,6 @@ SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 0
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false

View File

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

View File

@@ -11,13 +11,13 @@
class SerialTty : public Tty {
// TODO: Possibly there should be 2 mutexes?
Mutex mutex;
CV readercv;
CV isrcv;
static void isr(void *tty);
Mutex mutex;
CV readercv;
CV isrcv;
static void isr(void *tty);
void this_isr();
void this_pooler();
void this_isr();
void this_pooler();
CircularBuffer<char, 512> buf;
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) {
_sse_setup();
barrier();
gdt_setup();
Arch::GDT::gdt_setup();
barrier();
idt_init();
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);
}
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...
new_stack_top = reinterpret_cast<uint64_t *>(((uint64_t) new_stack_top) & (~0xFULL));// correct alignment for sse
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...
new_stack_top = reinterpret_cast<uint64_t *>(((uint64_t) new_stack_top) & (~0xFULL)); // correct alignment for sse
barrier();
__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 GRAN_4K | LONG_MODE | 0xF ; Flags & Limit (high, bits 16-19)
db 0 ; Base (high, bits 24-31)
global gdt_tss:data
gdt_tss:
dq 0x00000000 ;TODO
dq 0x00000000
dq 0x00000000
global gdt_tss_user:data
gdt_tss_user:
dq 0x00000000 ;TODO
dq 0x00000000
dq 0x00000000
global gdt_end:data
gdt_end:
global gdtr:data
gdtr:
dw gdt_end - gdt_null - 1
@@ -93,20 +96,23 @@ section .text
global _gdt_setup:function (_gdt_setup.end - _gdt_setup)
_gdt_setup:
LGDT [gdtr]
; Reload CS register:
PUSH (gdt_code - gdt_null); Push code segment to stack, 0x08 is a stand-in for your code segment
LEA RAX, [rel .flush] ; Load address of .reload_CS into RAX
PUSH RAX ; Push this value to the stack
RETFQ ; Perform a far return, RETFQ or LRETQ depending on syntax
; Reload CS register
PUSH (gdt_code - gdt_null) ; Push code segment to stack
LEA RAX, [rel .flush] ; Load address of .flush into RAX
PUSH RAX ; Push this value to the stack
RETFQ ; Perform a far return, RETFQ or LRETQ depending on syntax
.flush:
; 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 ES, AX
MOV FS, AX
MOV GS, AX
MOV SS, AX
MOV AX, (gdt_tss - gdt_null)
ltr AX
RET
.end:

View File

@@ -3,37 +3,45 @@
//
#include "gdt.hpp"
#include "asserts.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 struct tss_entry_struct tss_entry_user;
static constexpr size_t INT_STACK_SIZE = 16384;
static constexpr size_t RSP_STACK_SIZE = 16384;
#define INT_STACK_SIZE 16384
#define RSP_STACK_SIZE 16384
static uint64_t int_stack[INT_STACK_SIZE];
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);
uint64_t tss_base = (uint64_t) &tss_entry;
//
void gdt_setup() {
uint32_t tss_limit = sizeof(tss_entry);
uint64_t tss_base = (uint64_t) &tss_entry;
gdt_tss.limit_low = tss_limit & 0xFFFF;
gdt_tss.base_low = tss_base & 0xFFFFFF;
gdt_tss.type = 0b1001;// Available 64 bit TSS
gdt_tss.zero = 0;
gdt_tss.DPL = 0;
gdt_tss.present = 1;
gdt_tss.limit_high = (tss_limit >> 16) & 0xF;
gdt_tss.available = 0;
gdt_tss.unused = 0;
gdt_tss.gran = 0;
gdt_tss.base_high = (tss_base >> 24) & 0xFFFFFFFFFF;
gdt_tss.limit_low = tss_limit & 0xFFFF;
gdt_tss.base_low = tss_base & 0xFFFFFF;
gdt_tss.type = 0b1001; // Available 64 bit TSS
gdt_tss.zero = 0;
gdt_tss.DPL = 0;
gdt_tss.present = 1;
gdt_tss.limit_high = (tss_limit >> 16) & 0xF;
gdt_tss.available = 0;
gdt_tss.unused = 0;
gdt_tss.gran = 0;
gdt_tss.base_high = (tss_base >> 24) & 0xFFFFFFFFFF;
tss_entry.ist1 = (((uintptr_t) int_stack + (INT_STACK_SIZE - 9) - 1) & (~0xFULL)) + 8;
if ((tss_entry.ist1 & 0xFULL) != 8) _hcf();
tss_entry.rsp0 = (((uintptr_t) rsp_stack + (RSP_STACK_SIZE - 9) - 1) & (~0xFULL)) + 8;
if ((tss_entry.rsp0 & 0xFULL) != 8) _hcf();
tss_entry.ist1 = (((uintptr_t) int_stack + (INT_STACK_SIZE - 9) - 1) & (~0xFULL)) + 8;
assert((tss_entry.ist1 & 0xFULL) == 8);
barrier();// The asm function might clobber registers
_gdt_setup();
}
tss_entry.rsp0 = (((uintptr_t) rsp_stack + (RSP_STACK_SIZE - 9) - 1) & (~0xFULL)) + 8;
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>
struct gdt_entry_bits {
unsigned int limit_low : 16;
unsigned int base_low : 24;
unsigned int accessed : 1;
unsigned int read_write : 1; // readable for code, writable for data
unsigned int conforming_expand_down : 1;// conforming for code, expand down for data
unsigned int code : 1; // 1 for code, 0 for data
unsigned int code_data_segment : 1; // should be 1 for everything but TSS and LDT
unsigned int DPL : 2; // privilege level
unsigned int present : 1;
unsigned int limit_high : 4;
unsigned int available : 1;// only used in software; has no effect on hardware
unsigned int long_mode : 1;
unsigned int big : 1; // 32-bit opcodes for code, uint32_t stack for data
unsigned int gran : 1;// 1 to use 4k page addressing, 0 for byte addressing
unsigned int base_high : 8;
} __attribute__((packed));
namespace Arch::GDT {
struct gdt_entry_bits {
unsigned int limit_low : 16;
unsigned int base_low : 24;
unsigned int accessed : 1;
unsigned int read_write : 1; // readable for code, writable for data
unsigned int conforming_expand_down : 1; // conforming for code, expand down for data
unsigned int code : 1; // 1 for code, 0 for data
unsigned int code_data_segment : 1; // should be 1 for everything but TSS and LDT
unsigned int DPL : 2; // privilege level
unsigned int present : 1;
unsigned int limit_high : 4;
unsigned int available : 1; // only used in software; has no effect on hardware
unsigned int long_mode : 1;
unsigned int big : 1; // 32-bit opcodes for code, uint32_t stack for data
unsigned int gran : 1; // 1 to use 4k page addressing, 0 for byte addressing
unsigned int base_high : 8;
struct gdt_tss_entry_bits {
unsigned int limit_low : 16;
unsigned int base_low : 24;
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));
//
uint64_t selector() volatile;
} __attribute__((packed));
struct tss_entry_struct {
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));
struct gdt_tss_entry_bits {
unsigned int limit_low : 16;
unsigned int base_low : 24;
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));
extern "C" void _gdt_setup();
void gdt_setup();
struct tss_entry_struct {
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;
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;
void gdt_setup();
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 {
uint16_t limit;
uint64_t base;
} gdtr;
extern volatile struct gdt_entry_bits gdt_end; // It is not a pointer!
extern struct {
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

View File

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

View File

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

View File

@@ -4,47 +4,47 @@
#include <stddef.h>
#include <stdint.h>
#define PIC1 0x20 /* IO base address for master PIC */
#define PIC2 0xA0 /* IO base address for slave PIC */
#define PIC1_COMMAND PIC1
#define PIC1_DATA (PIC1 + 1)
#define PIC2_COMMAND PIC2
#define PIC2_DATA (PIC2 + 1)
#define PIC_EOI 0x20 /* End-of-interrupt command code */
#define PIC1 0x20 /* IO base address for master PIC */
#define PIC2 0xA0 /* IO base address for slave PIC */
#define PIC1_COMMAND PIC1
#define PIC1_DATA (PIC1 + 1)
#define PIC2_COMMAND PIC2
#define PIC2_DATA (PIC2 + 1)
#define PIC_EOI 0x20 /* End-of-interrupt command code */
#define ICW1_ICW4 0x01 /* Indicates that ICW4 will be present */
#define ICW1_SINGLE 0x02 /* Single (cascade) mode */
#define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */
#define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */
#define ICW1_INIT 0x10 /* Initialization - required! */
#define ICW1_ICW4 0x01 /* Indicates that ICW4 will be present */
#define ICW1_SINGLE 0x02 /* Single (cascade) mode */
#define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */
#define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */
#define ICW1_INIT 0x10 /* Initialization - required! */
#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */
#define ICW4_AUTO 0x02 /* Auto (normal) EOI */
#define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */
#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */
#define ICW4_AUTO 0x02 /* Auto (normal) EOI */
#define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */
#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */
#define ICW4_SFNM 0x10 /* Special fully nested (not) */
#define ICW4_SFNM 0x10 /* Special fully nested (not) */
#define PIC_READ_IRR 0x0a /* OCW3 irq ready next CMD read */
#define PIC_READ_ISR 0x0b /* OCW3 irq service next CMD read */
#define PIC_READ_IRR 0x0a /* OCW3 irq ready next CMD read */
#define PIC_READ_ISR 0x0b /* OCW3 irq service next CMD read */
#define PIC1_OFFSET 0x20
#define PIC2_OFFSET 0x28
#define PIC1_OFFSET 0x20
#define PIC2_OFFSET 0x28
void PIC_sendEOI(unsigned char irq);
void PIC_init();
void IRQ_set_mask(unsigned char IRQline);
void IRQ_clear_mask(unsigned char IRQline);
void PIC_sendEOI(unsigned char irq);
void PIC_init();
void IRQ_set_mask(unsigned char IRQline);
void IRQ_clear_mask(unsigned char IRQline);
uint16_t pic_get_irr(void);
uint16_t pic_get_isr(void);
typedef struct {
uint16_t isr_low; // The lower 16 bits of the ISR's address
uint16_t kernel_cs;// The GDT segment selector that the CPU will load into CS before calling the ISR
uint8_t ist; // The IST in the TSS that the CPU will load into RSP; set to zero for now
uint8_t attributes;// Type and attributes; see the IDT page
uint16_t isr_mid; // The higher 16 bits of the lower 32 bits of the ISR's address
uint32_t isr_high; // The higher 32 bits of the ISR's address
uint32_t reserved; // Set to zero
uint16_t isr_low; // The lower 16 bits of the ISR's address
uint16_t kernel_cs; // The GDT segment selector that the CPU will load into CS before calling the ISR
uint8_t ist; // The IST in the TSS that the CPU will load into RSP; set to zero for now
uint8_t attributes; // Type and attributes; see the IDT page
uint16_t isr_mid; // The higher 16 bits of the lower 32 bits of the ISR's address
uint32_t isr_high; // The higher 32 bits of the ISR's address
uint32_t reserved; // Set to zero
} __attribute__((packed)) idt_entry_t;
typedef struct {
@@ -57,7 +57,7 @@ typedef struct {
// Assuming the compiler understands that this is pushed on the stack in the correct order
struct task_frame {
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 r14;
@@ -84,16 +84,16 @@ struct task_frame {
} __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 *);
void attach_interrupt(unsigned num, int_handler_t handler, void *arg);
void attach_interrupt(unsigned num, int_handler_t handler, void *arg);
#endif

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -9,11 +9,11 @@
#include "paging.hpp"
void limine_fb_save_response(struct AddressSpace *boot_address_space);
void limine_fb_remap(struct AddressSpace *space);
void limine_fb_save_response(struct AddressSpace *boot_address_space);
void limine_fb_remap(struct AddressSpace *space);
extern int framebuffer_count;
extern int framebuffer_count;
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"
static volatile struct limine_memmap_request memmap_request = {
.id = LIMINE_MEMMAP_REQUEST,
.id = LIMINE_MEMMAP_REQUEST,
.revision = 0};
unsigned int limine_mm_count;
unsigned int limine_mm_count;
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;
if (limine_mm_count > LIMINE_MM_MAX) {
limine_mm_count = LIMINE_MM_MAX;
limine_mm_count = LIMINE_MM_MAX;
limine_mm_overflow = 1;
} else {
limine_mm_overflow = 0;

View File

@@ -9,10 +9,10 @@
#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 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"
static volatile struct limine_module_request module_request = {
.id = LIMINE_MODULE_REQUEST,
.id = LIMINE_MODULE_REQUEST,
.revision = 0};
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_names[max_saved_modules][max_saved_module_name] __attribute__((aligned(4096)));
unsigned saved_modules_size = 0;
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)));
unsigned saved_modules_size = 0;
void limine_modules_save() {
void limine_modules_save() {
for (int i = 0; i < module_request.response->module_count; i++) {
assert(i < max_saved_modules);
saved_modules_size++;

View File

@@ -7,15 +7,15 @@
#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_name = 256;
static constexpr unsigned max_saved_module_name = 256;
extern unsigned saved_modules_size;
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_names[max_saved_modules][max_saved_module_name] __attribute__((aligned(4096)));
extern unsigned saved_modules_size;
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_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>
#define MAXGB 32ULL
#define BITMAP_SIZE (((MAXGB) *1024ULL * 1024ULL) / (16ULL))
#define MAX_PID (((BITMAP_SIZE) *4) - 4)
#define MAXGB 32ULL
#define BITMAP_SIZE (((MAXGB) * 1024ULL * 1024ULL) / (16ULL))
#define MAX_PID (((BITMAP_SIZE) * 4) - 4)
// Expected to be nulled by the bootloader
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 minPid = 0;
static uint64_t totalMem = 0;// Past the end
static uint64_t maxPid = 0; // Past the end
static uint64_t minPid = 0;
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;
else {
return (addr + 0x1000) & (~(0xFFFULL));
@@ -40,7 +40,7 @@ static uint64_t rounddown4k(uint64_t addr) {
void setSts(uint64_t pid, enum PageStatus sts) {
uint64_t rounddown = pid & (~(0b11ULL));
uint64_t idx = rounddown >> 2;
uint64_t idx = rounddown >> 2;
switch (pid & 0b11ULL) {
case 0:
used_bitmap[idx].first = sts;
@@ -59,7 +59,7 @@ void setSts(uint64_t pid, enum PageStatus sts) {
enum PageStatus getSts(uint64_t pid) {
uint64_t rounddown = pid & (~(0b11ULL));
uint64_t idx = rounddown >> 2;
uint64_t idx = rounddown >> 2;
switch (pid & 0b11ULL) {
case 0:
return used_bitmap[idx].first;

View File

@@ -7,23 +7,23 @@
#include "limine.h"
enum PageStatus {
MEMMAN_STATE_FREE = 1,
MEMMAN_STATE_USED = 2,
MEMMAN_STATE_RESERVED = 0,
MEMMAN_STATE_FREE = 1,
MEMMAN_STATE_USED = 2,
MEMMAN_STATE_RESERVED = 0,
MEMMAN_STATE_RECLAIMABLE = 3,
};
struct FourPages {
enum PageStatus first : 2;
enum PageStatus first : 2;
enum PageStatus second : 2;
enum PageStatus third : 2;
enum PageStatus third : 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 free4k(void *page);
void *get4k();
void free4k(void *page);
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.
while (low < ptr) {
char tmp = *low;
*low++ = *ptr;
*ptr-- = tmp;
*low++ = *ptr;
*ptr-- = tmp;
}
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) {
uint32_t low = value & 0xFFFFFFFF;
uint32_t low = value & 0xFFFFFFFF;
uint32_t high = value >> 32;
asm volatile(
"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 < kernel_virt_base, "CR3 here must be in HDDM!");
uint64_t pml4i = (uint64_t) virt >> 39 & 0x01FF;
uint64_t pdpei = (uint64_t) virt >> 30 & 0x01FF;
uint64_t pdei = (uint64_t) virt >> 21 & 0x01FF;
uint64_t ptsi = (uint64_t) virt >> 12 & 0x01FF;
uint64_t pml4i = (uint64_t) virt >> 39 & 0x01FF;
uint64_t pdpei = (uint64_t) virt >> 30 & 0x01FF;
uint64_t pdei = (uint64_t) virt >> 21 & 0x01FF;
uint64_t ptsi = (uint64_t) virt >> 12 & 0x01FF;
uint64_t *pml4e = PML4 + pml4i;
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 < kernel_virt_base, "CR3 here must be in HDDM!");
uint64_t pml4i = (uint64_t) virt >> 39 & 0x01FF;
uint64_t pdpei = (uint64_t) virt >> 30 & 0x01FF;
uint64_t pdei = (uint64_t) virt >> 21 & 0x01FF;
uint64_t ptsi = (uint64_t) virt >> 12 & 0x01FF;
uint64_t pml4i = (uint64_t) virt >> 39 & 0x01FF;
uint64_t pdpei = (uint64_t) virt >> 30 & 0x01FF;
uint64_t pdei = (uint64_t) virt >> 21 & 0x01FF;
uint64_t ptsi = (uint64_t) virt >> 12 & 0x01FF;
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 *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));
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 < kernel_virt_base, "CR3 here must be in HDDM!");
uint64_t pml4i = (uint64_t) virt >> 39 & 0x01FF;
uint64_t pdpei = (uint64_t) virt >> 30 & 0x01FF;
uint64_t pdei = (uint64_t) virt >> 21 & 0x01FF;
uint64_t ptsi = (uint64_t) virt >> 12 & 0x01FF;
uint64_t pml4i = (uint64_t) virt >> 39 & 0x01FF;
uint64_t pdpei = (uint64_t) virt >> 30 & 0x01FF;
uint64_t pdei = (uint64_t) virt >> 21 & 0x01FF;
uint64_t ptsi = (uint64_t) virt >> 12 & 0x01FF;
uint64_t *pml4e = PML4 + pml4i;
@@ -168,7 +168,7 @@ FDT *AddressSpace::getFdt() {
}
static volatile struct limine_kernel_address_request kernel_address_request = {
.id = LIMINE_KERNEL_ADDRESS_REQUEST,
.id = LIMINE_KERNEL_ADDRESS_REQUEST,
.revision = 0};
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_used = 0;
uintptr_t kernel_phys_base;
uintptr_t kernel_virt_base;
uintptr_t kernel_phys_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_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 we're using Limine
for (uint64_t i = 0; i < HHDM_SIZE; i++) {
void *virt = (void *) (HHDM_BEGIN + i * 1024ULL * 1024ULL * 1024ULL);
void *real = (void *) (i * 1024ULL * 1024ULL * 1024ULL);
void *virt = (void *) (HHDM_BEGIN + i * 1024ULL * 1024ULL * 1024ULL);
void *real = (void *) (i * 1024ULL * 1024ULL * 1024ULL);
uint64_t pml4i = (uint64_t) virt >> 39 & 0x01FF;
uint64_t pdpei = (uint64_t) virt >> 30 & 0x01FF;

View File

@@ -10,13 +10,13 @@
#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_P2V(a) ((((uintptr_t) (a) -kernel_phys_base) | kernel_virt_base))
#define HHDM_BEGIN 0xfffff80000000000ULL
#define HHDM_SIZE 32ULL// In GB
#define HHDM_BEGIN 0xfffff80000000000ULL
#define HHDM_SIZE 32ULL // In GB
#define HHDM_V2P(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();
void *virt2real(void *virt);
int map(void *virt, void *real, uint32_t flags);
int unmap(void *virt);
void *virt2real(void *virt);
int map(void *virt, void *real, uint32_t flags);
int unmap(void *virt);
uint64_t *get_cr3() {
return PML4;
@@ -46,22 +46,22 @@ private:
// Pointer to PML4 in HDDM
uint64_t *PML4;
FDT *_fdt = nullptr;
FDT *_fdt = nullptr;
};
extern AddressSpace *KERN_AddressSpace;
extern uintptr_t kernel_phys_base;
extern uintptr_t kernel_virt_base;
void limine_kern_save_response();
extern uintptr_t kernel_phys_base;
extern uintptr_t kernel_virt_base;
void limine_kern_save_response();
#define PAGE_PS (1 << 7)
#define PAGE_RW (1 << 1)
#define PAGE_USER (1 << 2)
#define PAGE_PS (1 << 7)
#define PAGE_RW (1 << 1)
#define PAGE_USER (1 << 2)
#define PAGE_PRESENT (0x01ULL)
void map_hddm(uint64_t *pml4);
void map_hddm(uint64_t *pml4);
extern "C" void _tlb_flush();
#endif//OS1_PAGING_H
#endif //OS1_PAGING_H

View File

@@ -9,18 +9,18 @@
#include "io.hpp"
#include "task.hpp"
#define PORT 0x3f8// COM1
#define PORT 0x3f8 // COM1
int init_serial() {
outb(PORT + 1, 0x00);// Disable all interrupts
outb(PORT + 3, 0x80);// Enable DLAB (set baud rate divisor)
outb(PORT + 0, 0x03);// Set divisor to 3 (lo byte) 38400 baud
outb(PORT + 1, 0x00);// (hi byte)
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 + 4, 0x0B);// IRQs enabled, RTS/DSR set
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 + 1, 0x00); // Disable all interrupts
outb(PORT + 3, 0x80); // Enable DLAB (set baud rate divisor)
outb(PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud
outb(PORT + 1, 0x00); // (hi byte)
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 + 4, 0x0B); // IRQs enabled, RTS/DSR set
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)
// Check if serial is faulty (i.e: not same byte as sent)
if (inb(PORT + 0) != 0xAE) {

View File

@@ -7,15 +7,15 @@
#include "misc.hpp"
int init_serial();
int init_serial();
int serial_received();
int serial_received();
char read_serial();
int is_transmit_empty();
int is_transmit_empty();
void write_serial(char a);
void writestr(const char *a);
void write_serial_no_yield(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
// But what happens with something more complex is completely bonkers
struct STAR {
unsigned unused : 32;
unsigned unused : 32;
unsigned call_cs_ss : 16;
unsigned ret_cs_ss : 16;
unsigned ret_cs_ss : 16;
} __attribute__((packed));
static_assert(sizeof(STAR) == 8);
void setup_syscalls() {
union {
STAR star;
STAR star;
uint64_t bytes;
} __attribute__((__packed__)) newstar{};
newstar.star.ret_cs_ss = (GDTSEL(gdt_data_user) - 8) | 0x3;
assert(newstar.star.ret_cs_ss + 8 == (GDTSEL(gdt_data_user) | 0x3));
assert(newstar.star.ret_cs_ss + 16 == (GDTSEL(gdt_code_user) | 0x3));
newstar.star.ret_cs_ss = (Arch::GDT::gdt_data_user.selector() - 8) | 0x3;
assert(newstar.star.ret_cs_ss + 8 == (Arch::GDT::gdt_data_user.selector() | 0x3));
assert(newstar.star.ret_cs_ss + 16 == (Arch::GDT::gdt_code_user.selector() | 0x3));
newstar.star.call_cs_ss = (GDTSEL(gdt_code));
assert(newstar.star.call_cs_ss == GDTSEL(gdt_code));
assert(newstar.star.call_cs_ss + 8 == GDTSEL(gdt_data));
newstar.star.call_cs_ss = (Arch::GDT::gdt_code.selector());
assert(newstar.star.call_cs_ss == Arch::GDT::gdt_code.selector());
assert(newstar.star.call_cs_ss + 8 == Arch::GDT::gdt_data.selector());
wrmsr(0xc0000081, newstar.bytes);
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);
}

View File

@@ -7,9 +7,9 @@
#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);
#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->cs != 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->cs == GDTSEL(gdt_code) || (cur_frame->ss == GDTSEL(gdt_code_user)) | 0x3), "CS 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 == Arch::GDT::gdt_code.selector() || (cur_frame->ss == Arch::GDT::gdt_code_user.selector()) | 0x3), "CS wrong!");
}
std::atomic<uint64_t> max_pid = 0;
Mutex AllTasks_lock;
std::atomic<uint64_t> max_pid = 0;
Mutex AllTasks_lock;
SkipList<uint64_t, Task *> AllTasks;
static List<Task *>::Node *RunningTask;
static Spinlock NextTasks_lock;
static List<Task *> NextTasks;
static Spinlock NextTasks_lock;
static List<Task *> NextTasks;
// Task freer
Mutex TasksToFree_lock;
CV TasksToFree_cv;
Mutex TasksToFree_lock;
CV TasksToFree_cv;
List<List<Task *>::Node *> TasksToFree;
// Waiting
Mutex WaitingTasks_mlock;
CV WaitingTasks_cv;
Mutex WaitingTasks_mlock;
CV WaitingTasks_cv;
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->name);
kfree(t->fxsave);
@@ -110,28 +110,28 @@ static void task_freer() {
struct Task *new_ktask(void (*fn)(), const char *name, bool start) {
struct Task *newt = static_cast<Task *>(kmalloc(sizeof(struct Task)));
newt->kstack = static_cast<uint64_t *>(kmalloc(TASK_SS));
newt->name = static_cast<char *>(kmalloc(strlen(name) + 1));
newt->fxsave = static_cast<char *>(kmalloc(512));
newt->kstack = static_cast<uint64_t *>(kmalloc(TASK_SS));
newt->name = static_cast<char *>(kmalloc(strlen(name) + 1));
newt->fxsave = static_cast<char *>(kmalloc(512));
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
assert((newt->frame.sp & 0xFULL) == 8);
newt->frame.ip = (uint64_t) fn;
newt->frame.cs = GDTSEL(gdt_code);
newt->frame.ss = GDTSEL(gdt_data);
newt->frame.cs = Arch::GDT::gdt_code.selector();
newt->frame.ss = Arch::GDT::gdt_data.selector();
for (int i = 0; i < 512; i++) newt->fxsave[i] = 0;
newt->frame.flags = flags();
newt->frame.guard = IDT_GUARD;
newt->frame.flags = flags();
newt->frame.guard = IDT_GUARD;
newt->addressSpace = KERN_AddressSpace;
newt->state = start ? TS_RUNNING : TS_BLOCKED;
newt->mode = TASKMODE_KERN;
newt->pid = max_pid.fetch_add(1);
newt->used_time = 0;
newt->state = start ? TS_RUNNING : TS_BLOCKED;
newt->mode = TASKMODE_KERN;
newt->pid = max_pid.fetch_add(1);
newt->used_time = 0;
sanity_check_frame(&newt->frame);
if (start) {
@@ -150,45 +150,45 @@ struct Task *new_ktask(void (*fn)(), const char *name, bool start) {
return newt;
}
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->name = static_cast<char *>(kmalloc(strlen(name) + 1));
newt->name = static_cast<char *>(kmalloc(strlen(name) + 1));
newt->fxsave = static_cast<char *>(kmalloc(512));
strcpy(name, newt->name);
newt->frame.ip = (uint64_t) entrypoint;
newt->frame.cs = GDTSEL(gdt_code_user) | 0x3;
newt->frame.ss = GDTSEL(gdt_data_user) | 0x3;
newt->frame.cs = Arch::GDT::gdt_code_user.selector() | 0x3;
newt->frame.ss = Arch::GDT::gdt_data_user.selector() | 0x3;
for (int i = 0; i < 512; i++) newt->fxsave[i] = 0;
newt->frame.flags = flags();
newt->frame.guard = IDT_GUARD;
newt->addressSpace = new AddressSpace();
newt->vma = new VMA(newt->addressSpace);
newt->state = TS_BLOCKED;
newt->mode = TASKMODE_USER;
newt->pid = max_pid.fetch_add(1);
newt->used_time = 0;
newt->frame.flags = flags();
newt->frame.guard = IDT_GUARD;
newt->addressSpace = new AddressSpace();
newt->vma = new VMA(newt->addressSpace);
newt->state = TS_BLOCKED;
newt->mode = TASKMODE_USER;
newt->pid = max_pid.fetch_add(1);
newt->used_time = 0;
task_pointer *taskptr = static_cast<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);
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
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->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
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) {
assert(task->state != TS_RUNNING);
task->state = TS_RUNNING;
task->state = TS_RUNNING;
auto new_node = NextTasks.create_node(task);
{
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) {
auto *node = &*WaitingTasks.begin();
auto task = WaitingTasks.begin()->data;
auto task = WaitingTasks.begin()->data;
// TODO this is all ugly
uint64_t l1 = 0;
@@ -282,7 +282,7 @@ static void task_waker() {
assert(l1 - l2 == 1);
task->val->sleep_until = 0;
task->val->state = TS_RUNNING;
task->val->state = TS_RUNNING;
{
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;
{
SpinlockLockNoIntAssert ntl(NextTasks_lock);
static uint64_t lastSwitchMicros = 0;
uint64_t prevSwitchMicros = lastSwitchMicros;
lastSwitchMicros = micros;
static uint64_t lastSwitchMicros = 0;
uint64_t prevSwitchMicros = lastSwitchMicros;
lastSwitchMicros = micros;
if (RunningTask) {
RunningTask->val->frame = *cur_frame;
@@ -352,7 +352,7 @@ extern "C" void switch_task(struct task_frame *cur_frame) {
}
RunningTask = next;
*cur_frame = RunningTask->val->frame;
*cur_frame = RunningTask->val->frame;
__builtin_memcpy(temp_fxsave, RunningTask->val->fxsave, 512);
AddressSpace *newspace = RunningTask->val->addressSpace;

View File

@@ -28,43 +28,43 @@ struct AddressSpace;
class VMA;
struct Task {
uint64_t entry_ksp_val;
struct task_frame frame;
uint64_t pid;
uint64_t entry_ksp_val;
struct task_frame frame;
uint64_t pid;
std::atomic<uint64_t> used_time;
AddressSpace *addressSpace;
VMA *vma;
uint64_t *kstack;
char *fxsave;
char *name;
enum TaskMode mode;
uint64_t sleep_until;
enum TaskState state;
AddressSpace *addressSpace;
VMA *vma;
uint64_t *kstack;
char *fxsave;
char *name;
enum TaskMode mode;
uint64_t sleep_until;
enum TaskState state;
};
struct task_pointer {
Task *taskptr;
Task *taskptr;
uint64_t entry_ksp_val;
uint64_t ret_sp;
uint64_t ret_flags;
} __attribute__((packed));
struct Task *cur_task();
struct Task *cur_task();
List<Task *>::Node *extract_running_task_node();
void init_tasks();
struct Task *new_ktask(void (*fn)(), const char *name, bool start = true);
struct Task *new_utask(void (*entrypoint)(), const char *name);
void init_tasks();
struct Task *new_ktask(void (*fn)(), const char *name, bool start = true);
struct Task *new_utask(void (*entrypoint)(), const char *name);
List<Task *>::Node *start_task(struct Task *task);
void remove_self();
void sleep_self(uint64_t diff);
void remove_self();
void sleep_self(uint64_t diff);
void self_block();
void self_block();
class Spinlock;
void self_block(Spinlock &to_unlock);
void unblock(Task *what);
void unblock(List<Task *>::Node *what);
void self_block(Spinlock &to_unlock);
void unblock(Task *what);
void unblock(List<Task *>::Node *what);
extern "C" void switch_task(struct task_frame *cur_frame);
@@ -73,8 +73,8 @@ using TaskPID = uint64_t;
// TODO: that's quite inefficient!
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> micros;
unsigned read_pit_count(void) {
unsigned read_pit_count(void) {
unsigned count = 0;
// Disable interrupts
@@ -19,8 +19,8 @@ unsigned read_pit_count(void) {
// al = channel in bits 6 and 7, remaining bits clear
outb(0x43, 0b0000000);
count = inb(0x40); // Low byte
count |= inb(0x40) << 8;// High byte
count = inb(0x40); // Low byte
count |= inb(0x40) << 8; // High byte
return count;
}
@@ -30,15 +30,15 @@ void set_pit_count(unsigned count) {
// cli();
// Set low byte
outb(0x40, count & 0xFF); // Low byte
outb(0x40, (count & 0xFF00) >> 8);// High byte
outb(0x40, count & 0xFF); // Low byte
outb(0x40, (count & 0xFF00) >> 8); // High byte
return;
}
// Very rough but I don't care right now
// About 1000 HZ freq
#define RELOAD_VAL 1193
#define FREQ (1193182 / (RELOAD_VAL))
#define RELOAD_VAL 1193
#define FREQ (1193182 / (RELOAD_VAL))
#define MICROS_PER_TICK (1000000 / (FREQ))
void init_timer() {

View File

@@ -11,7 +11,7 @@
extern volatile std::atomic<uint64_t> ticks;
extern volatile std::atomic<uint64_t> micros;
void init_timer();
void timer_tick();
void init_timer();
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) {
auto fmt = format(bytes);
auto fmt = format(bytes);
String out;
out += fmt.number;
out += " ";

View File

@@ -12,8 +12,8 @@ class BytesFormatter {
public:
/// Structure for returning the processed byte value
struct BytesFormat {
String number;///< Number part of the value
String prefix;///< Unit of measure
String number; ///< Number part of the value
String prefix; ///< Unit of measure
};
/// 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:
T *_lock;
T *_lock;
bool suc;
};
#endif//OS2_LOCKGUARD_H
#endif //OS2_LOCKGUARD_H

View File

@@ -24,7 +24,7 @@ public:
void spinlock() {
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() {
@@ -44,7 +44,7 @@ public:
private:
std::atomic<bool> locked = false;
Task *owner;
Task *owner;
};
static_assert(std::is_trivially_copyable_v<Spinlock> == true);
@@ -80,8 +80,8 @@ public:
SpinlockLockNoInt(SpinlockLockNoInt const &d) = delete;
private:
Spinlock *lock;
Spinlock *lock;
unsigned long f;
};
#endif//OS2_SPINLOCK_H
#endif //OS2_SPINLOCK_H

View File

@@ -9,10 +9,10 @@
#include "mutex.hpp"
class Tty {
public:
virtual void putchar(char c) = 0;
virtual void putchar(char c) = 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 "mutex.hpp"
TtyManager GlobalTtyManager;
TtyManager GlobalTtyManager;
Vector<TtyManager> ttys;
void TtyManager::add_tty(Tty *tty) {
void TtyManager::add_tty(Tty *tty) {
LockGuard l(lock);
ttys.emplace_back(tty);
}

View File

@@ -10,19 +10,19 @@
#include "Vector.hpp"
class TtyManager {
Mutex lock;
Mutex lock;
Vector<Tty *> ttys;
public:
void add_tty(Tty *tty);
void add_tty(Tty *tty);
void all_tty_putchar(char c);
void all_tty_putstr(const char *str);
void all_tty_putchar(char c);
void all_tty_putstr(const char *str);
unsigned get_num_ttys();
Tty *get_tty(unsigned n);
Tty *get_tty(unsigned n);
};
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);
}
assert((length & (PAGE_SIZE - 1)) == 0);
uint64_t page_len = length / PAGE_SIZE;
uint64_t page_len = length / PAGE_SIZE;
std::optional<ListEntry> found;
{

View File

@@ -21,24 +21,24 @@ public:
/// Map all higher-half pages into the address space
/// 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_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:
AddressSpace *space = nullptr;
Mutex space_lock;
Mutex space_lock;
struct ListEntry {
uintptr_t begin;
uint64_t length;
bool available;
uint64_t length;
bool available;
};
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 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
#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) {
assert2(false, "Stack protection triggered!");
@@ -32,11 +32,11 @@ namespace __cxxabiv1 {
/* The ABI requires a 64-bit type. */
__extension__ typedef int __guard __attribute__((mode(__DI__)));
extern "C" int __cxa_guard_acquire(__guard *);
extern "C" void __cxa_guard_release(__guard *);
extern "C" void __cxa_guard_abort(__guard *);
extern "C" int __cxa_guard_acquire(__guard *);
extern "C" void __cxa_guard_release(__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);
}
@@ -47,7 +47,7 @@ namespace __cxxabiv1 {
extern "C" void __cxa_guard_abort(__guard *) {
_hcf();
}
}// namespace __cxxabiv1
} // namespace __cxxabiv1
void *operator new(size_t size) {
return kmalloc(size);

View File

@@ -18,7 +18,7 @@ struct Task;
// This is probably broken in some way
class CV {
List<Task *> waiters;
Spinlock waiters_lock;
Spinlock waiters_lock;
public:
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() {
bool expected = true;
_owner = nullptr;
_owner = nullptr;
if (!locked.compare_exchange_strong(expected, false))
assert2(false, "Unlocking an unlocked mutex!\n");
List<Task *>::Node *t = nullptr;

View File

@@ -21,20 +21,20 @@ public:
void lock();
// void spin_lock();
bool try_lock();
void unlock();
bool test();
bool try_lock();
void unlock();
bool test();
Task *owner() { return _owner; }
private:
std::atomic<bool> locked = false;
List<Task *> waiters;
Spinlock waiters_lock;
List<Task *> waiters;
Spinlock waiters_lock;
Task *_owner = nullptr;
uint8_t spin_success = 127;
Task *_owner = nullptr;
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.
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;
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.
#define RAND_MAX 32767
int rand(void);
int rand(void);
void srand(unsigned int seed);
#ifdef __cplusplus
}
#endif
#endif//OS2_RAND_H
#endif //OS2_RAND_H

View File

@@ -13,8 +13,8 @@ extern "C" {
#include <stdint.h>
inline void *memcpy(void *dest, const void *src, size_t n) {
uint8_t *pdest = (uint8_t *) dest;
const uint8_t *psrc = (const uint8_t *) src;
uint8_t *pdest = (uint8_t *) dest;
const uint8_t *psrc = (const uint8_t *) src;
for (size_t i = 0; i < n; 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) {
uint8_t *pdest = (uint8_t *) dest;
const uint8_t *psrc = (const uint8_t *) src;
uint8_t *pdest = (uint8_t *) dest;
const uint8_t *psrc = (const uint8_t *) src;
if (src > dest) {
for (size_t i = 0; i < n; i++) {
@@ -106,4 +106,4 @@ inline void strcpy(const char *src, char *dst) {
}
#endif
#endif//OS2_STRING_H
#endif //OS2_STRING_H

View File

@@ -10,13 +10,13 @@
// FIXME
template<typename T, auto S>
class CircularBuffer {
T data[S];
T data[S];
int front, back;
public:
CircularBuffer() {
front = -1;
back = -1;
back = -1;
}
bool full() {
@@ -41,7 +41,7 @@ public:
assert(false);
} else {
if (front == -1) front = 0;
back = (back + 1) % S;
back = (back + 1) % S;
data[back] = what;
}
}
@@ -53,7 +53,7 @@ public:
T ret = data[front];
if (front == back) {
front = -1;
back = -1;
back = -1;
} else {
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 {
public:
struct Node {
T val;
T val;
Node *next;
List *list;
};
private:
Node *head = nullptr;
Node *tail = nullptr;
Node *head = nullptr;
Node *tail = nullptr;
uint64_t size = 0;
@@ -51,7 +51,7 @@ public:
assert(tail != nullptr);
assert(size > 0);
head->next = new_node;
head = new_node;
head = new_node;
} else {
assert(size == 0);
head = new_node;
@@ -63,7 +63,7 @@ public:
bool empty() const {
return tail == nullptr;
}
T &back() {
if (tail != nullptr) {
assert(size > 0);
@@ -99,7 +99,7 @@ public:
}
auto old_tail = tail;
tail = tail->next;
tail = tail->next;
delete old_tail;
}
@@ -113,15 +113,15 @@ public:
size--;
if (tail == head) {
assert(size == 0);
auto b = tail;
tail = nullptr;
head = nullptr;
auto b = tail;
tail = nullptr;
head = nullptr;
b->list = nullptr;
return b;
}
auto old_tail = tail;
tail = tail->next;
auto old_tail = tail;
tail = tail->next;
old_tail->list = nullptr;
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;
}
UniquePtr(UniquePtr const &other) = delete;
UniquePtr(UniquePtr const &other) = delete;
UniquePtr &operator=(UniquePtr const &other) = delete;
UniquePtr(UniquePtr &&other) {
delete ptr;
ptr = other.ptr;
ptr = other.ptr;
other.ptr = nullptr;
}
UniquePtr &operator=(UniquePtr &&other) {
delete ptr;
ptr = other.ptr;
ptr = other.ptr;
other.ptr = nullptr;
return *this;
}
@@ -46,7 +46,7 @@ public:
T *release() noexcept {
auto b = ptr;
ptr = nullptr;
ptr = nullptr;
return b;
}
@@ -77,10 +77,10 @@ public:
}
SharedPtr(SharedPtr &&other) {
uses = other.uses;
ptr = other.ptr;
uses = other.uses;
ptr = other.ptr;
other.uses = nullptr;
other.ptr = nullptr;
other.ptr = nullptr;
}
SharedPtr &operator=(SharedPtr other) {
@@ -89,16 +89,16 @@ public:
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; }
private:
T *ptr = nullptr;
T *ptr = nullptr;
int *uses = nullptr;
};
@@ -110,7 +110,7 @@ private:
friend COWTester;
SharedPtr<T> ptr;
void copy() {
void copy() {
if (ptr.get() && ptr.useCount() > 1) {
ptr = SharedPtr<T>(new T(*ptr));
}
@@ -123,7 +123,7 @@ public:
explicit COWPointer(SharedPtr<T> data) : ptr(std::move(data)) {}
COWPointer(COWPointer &&other) = default;
COWPointer(COWPointer &&other) = default;
COWPointer(COWPointer const &data) = default;
@@ -143,7 +143,7 @@ public:
return ptr.get();
}
int useCount() { return ptr.useCount(); };
int useCount() { return ptr.useCount(); };
const T &operator*() const {
return *ptr;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -15,8 +15,8 @@ class MemFs : public Filesystem {
struct MemFsNodeDir : public NodeDir {
public:
Vector<Node *> children() override;
NodeDir *mkdir(const String &name) override;
NodeFile *mkfile(const String &name) override;
NodeDir *mkdir(const String &name) override;
NodeFile *mkfile(const String &name) override;
private:
SkipList<String, Node *> _children;
@@ -26,8 +26,8 @@ class MemFs : public Filesystem {
public:
MemFsNodeFile(const String &name) { _name = name; }
bool read(char *buf, size_t start, size_t num) override;
bool write(const 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;
size_t size() override;
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::traverse(const Path &path) {
NodeDir &nodeDir = static_cast<NodeDir &>(*this);
NodeDir &nodeDir = static_cast<NodeDir &>(*this);
Filesystem *mnt;
{
LockGuard l(_lock);

View File

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

View File

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

View File

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

View File

@@ -8,7 +8,7 @@
#include "Node.hpp"
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));
if (root_fd.get() == -1) return false;
File *root_f = FDT::current()->get(root_fd.get());
@@ -17,7 +17,7 @@ bool VFSApi::mkdir(const Path &path) {
return true;
}
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));
if (root_fd.get() == -1) return false;
File *root_f = FDT::current()->get(root_fd.get());

View File

@@ -10,14 +10,14 @@
#include "Path.hpp"
namespace VFSApi {
bool mkdir(const Path &path);
bool touch(const Path &path);
bool mkdir(const Path &path);
bool touch(const Path &path);
FDT::FD open(const Path &path);
File *get(FDT::FD fd);
void close(FDT::FD fd);
File *get(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;

View File

@@ -11,14 +11,14 @@
class RootNode : public NodeDir {
public:
Vector<Node *> children() override;
NodeDir *mkdir(const String &name) override;
NodeFile *mkfile(const String &name) override;
NodeDir *mkdir(const String &name) override;
NodeFile *mkfile(const String &name) override;
};
namespace VFSGlobals {
extern RootNode root;
extern RootNode root;
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"));
{
String t("hello wooooorld");
File *cf = VFSApi::get(c);
File *cf = VFSApi::get(c);
cf->write(t.c_str(), t.length() + 1);
}
assert(a != -1);
@@ -35,13 +35,13 @@ void VFSTester::test() {
assert(c != -1);
{
String t("aaaaaaaaaaaaaaaaaaaa");
File *cf = VFSApi::get(c);
File *cf = VFSApi::get(c);
cf->read(t.data(), cf->size());
assert(t == "hello wooooorld");
}
{
String t("aaaaaaaaaaaaaaaaaaaa");
File *cf = VFSApi::get(c);
File *cf = VFSApi::get(c);
cf->seek(0);
cf->read(t.data(), 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('i');
// 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";
write(test123, teststr, 9);
close(test123);

View File

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

View File

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

View File

@@ -14,25 +14,25 @@ extern "C" {
#include "FileOpts.h"
#define SYSCALL_PUTCHAR_ID 1
#define SYSCALL_SLEEP_ID 2
#define SYSCALL_PUTCHAR_ID 1
#define SYSCALL_SLEEP_ID 2
#define SYSCALL_READCHAR_ID 3
#define SYSCALL_OPEN_ID 4
#define SYSCALL_CLOSE_ID 5
#define SYSCALL_OPEN_ID 4
#define SYSCALL_CLOSE_ID 5
#define SYSCALL_READ_ID 6
#define SYSCALL_WRITE_ID 7
#define SYSCALL_LSEEK_ID 8
#define SYSCALL_READ_ID 6
#define SYSCALL_WRITE_ID 7
#define SYSCALL_LSEEK_ID 8
#define SYSCALL_OPENDIR_ID 9
#define SYSCALL_READDIR_ID 10
#define SYSCALL_OPENDIR_ID 9
#define SYSCALL_READDIR_ID 10
#define SYSCALL_CLOSEDIR_ID 11
#define SYSCALL_MKDIR_ID 12
#define SYSCALL_UNLINK_ID 13
#define SYSCALL_MKDIR_ID 12
#define SYSCALL_UNLINK_ID 13
#ifdef __cplusplus
}
#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 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)
: "D"(id_rdi), "S"(a1_rsi), "d"(a2_rdx), "a"(a3_rcx)
: "cc", "rcx", "r8",

View File

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