mirror of
https://github.com/usatiuk/ficus.git
synced 2025-10-29 00:27:52 +01:00
roughly add c++
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
cmake_minimum_required(VERSION 3.26)
|
||||
|
||||
project(os2 C ASM_NASM)
|
||||
project(os2 C CXX ASM_NASM)
|
||||
|
||||
#set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
|
||||
add_subdirectory(./src/)
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
|
||||
add_executable(kernel.elf)
|
||||
|
||||
target_compile_options(kernel.elf PUBLIC $<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions -fno-rtti -ffreestanding>)
|
||||
target_compile_options(kernel.elf PUBLIC $<$<COMPILE_LANGUAGE:C>:-ffreestanding>)
|
||||
|
||||
add_subdirectory(./arch/)
|
||||
add_subdirectory(./kernel/)
|
||||
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
|
||||
target_sources(kernel.elf PRIVATE
|
||||
limine_mm.c
|
||||
limine_mm.cpp
|
||||
task.asm
|
||||
tty.c
|
||||
kmem.c
|
||||
tty.cpp
|
||||
kmem.cpp
|
||||
kmain.asm
|
||||
paging.asm
|
||||
gdt.asm
|
||||
misc.asm
|
||||
limine_fb.c
|
||||
idt.c
|
||||
serial.c
|
||||
limine_fb.cpp
|
||||
idt.cpp
|
||||
serial.cpp
|
||||
idt.asm
|
||||
globals.c
|
||||
memman.c
|
||||
timer.c
|
||||
boot.c
|
||||
io.c
|
||||
task.c
|
||||
paging.c
|
||||
kmain.c
|
||||
gdt.c
|
||||
misc.c)
|
||||
globals.cpp
|
||||
memman.cpp
|
||||
timer.cpp
|
||||
boot.cpp
|
||||
io.cpp
|
||||
task.cpp
|
||||
paging.cpp
|
||||
kmain.cpp
|
||||
gdt.cpp
|
||||
misc.cpp)
|
||||
|
||||
target_include_directories(kernel.elf PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#include "gdt.h"
|
||||
#include "globals.h"
|
||||
#include "idt.h"
|
||||
#include "kmem.h"
|
||||
#include "gdt.hpp"
|
||||
#include "globals.hpp"
|
||||
#include "idt.hpp"
|
||||
#include "kmem.hpp"
|
||||
#include "limine.h"
|
||||
#include "limine_fb.h"
|
||||
#include "limine_mm.h"
|
||||
#include "memman.h"
|
||||
#include "misc.h"
|
||||
#include "paging.h"
|
||||
#include "serial.h"
|
||||
#include "limine_fb.hpp"
|
||||
#include "limine_mm.hpp"
|
||||
#include "memman.hpp"
|
||||
#include "misc.hpp"
|
||||
#include "paging.hpp"
|
||||
#include "serial.hpp"
|
||||
|
||||
struct AddressSpace BOOT_AddressSpace;
|
||||
|
||||
extern void kmain();
|
||||
|
||||
// Do final preparations in the new address space then call kmain
|
||||
__attribute__((noreturn))
|
||||
__attribute__((used))
|
||||
void real_start() {
|
||||
extern "C" __attribute__((noreturn))
|
||||
__attribute__((used)) void
|
||||
real_start() {
|
||||
parse_limine_memmap(limine_mm_entries, limine_mm_count, LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE);
|
||||
limine_fb_remap(KERN_AddressSpace);
|
||||
init_kern_heap();
|
||||
@@ -29,7 +29,7 @@ void real_start() {
|
||||
|
||||
// Set up the address space for the kernel and prepare other structures to work without the bootloader,
|
||||
// then call real_start with this address space and the new stack.
|
||||
void _start(void) {
|
||||
extern "C" void _start(void) {
|
||||
_sse_setup();
|
||||
barrier();
|
||||
gdt_setup();
|
||||
@@ -49,7 +49,7 @@ void _start(void) {
|
||||
|
||||
parse_limine_memmap(limine_mm_entries, limine_mm_count, LIMINE_MEMMAP_USABLE);
|
||||
|
||||
KERN_AddressSpace = get4k();
|
||||
KERN_AddressSpace = static_cast<AddressSpace *>(get4k());
|
||||
assert2(!init_addr_space(KERN_AddressSpace), "Couldn't init kernel address space!");
|
||||
|
||||
for (int i = 0; i < 512; i++)
|
||||
@@ -2,8 +2,8 @@
|
||||
// Created by Stepan Usatiuk on 13.08.2023.
|
||||
//
|
||||
|
||||
#include "gdt.h"
|
||||
#include "misc.h"
|
||||
#include "gdt.hpp"
|
||||
#include "misc.hpp"
|
||||
|
||||
static struct tss_entry_struct tss_entry;
|
||||
static struct tss_entry_struct tss_entry_user;
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef OS1_GDT_H
|
||||
#define OS1_GDT_H
|
||||
|
||||
#include "stdint.h"
|
||||
#include <cstdint>
|
||||
|
||||
struct gdt_entry_bits {
|
||||
unsigned int limit_low : 16;
|
||||
@@ -53,7 +53,7 @@ struct tss_entry_struct {
|
||||
uint32_t reserved4;
|
||||
} __attribute__((packed));
|
||||
|
||||
void _gdt_setup();
|
||||
extern "C" void _gdt_setup();
|
||||
void gdt_setup();
|
||||
|
||||
extern volatile struct gdt_entry_bits gdt_null;
|
||||
@@ -2,6 +2,6 @@
|
||||
// Created by Stepan Usatiuk on 13.08.2023.
|
||||
//
|
||||
|
||||
#include "globals.h"
|
||||
#include "globals.hpp"
|
||||
|
||||
uint64_t KERN_stack[KERN_STACK_SIZE] __attribute__((aligned(16)));
|
||||
@@ -1,39 +1,39 @@
|
||||
#include "idt.h"
|
||||
#include "idt.hpp"
|
||||
|
||||
#include "gdt.h"
|
||||
#include "io.h"
|
||||
#include "misc.h"
|
||||
#include "serial.h"
|
||||
#include "task.h"
|
||||
#include "timer.h"
|
||||
#include "gdt.hpp"
|
||||
#include "io.hpp"
|
||||
#include "misc.hpp"
|
||||
#include "serial.hpp"
|
||||
#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__((noreturn)) void exception_handler(void) {
|
||||
extern "C" __attribute__((noreturn)) void exception_handler(void) {
|
||||
_hcf();
|
||||
}
|
||||
|
||||
extern void pic1_irq_0();
|
||||
extern void pic1_irq_1();
|
||||
extern void pic1_irq_2();
|
||||
extern void pic1_irq_3();
|
||||
extern void pic1_irq_4();
|
||||
extern void pic1_irq_5();
|
||||
extern void pic1_irq_6();
|
||||
extern void pic1_irq_7();
|
||||
extern "C" void pic1_irq_0();
|
||||
extern "C" void pic1_irq_1();
|
||||
extern "C" void pic1_irq_2();
|
||||
extern "C" void pic1_irq_3();
|
||||
extern "C" void pic1_irq_4();
|
||||
extern "C" void pic1_irq_5();
|
||||
extern "C" void pic1_irq_6();
|
||||
extern "C" void pic1_irq_7();
|
||||
|
||||
extern void pic2_irq_0();
|
||||
extern void pic2_irq_1();
|
||||
extern void pic2_irq_2();
|
||||
extern void pic2_irq_3();
|
||||
extern void pic2_irq_4();
|
||||
extern void pic2_irq_5();
|
||||
extern void pic2_irq_6();
|
||||
extern void pic2_irq_7();
|
||||
extern "C" void pic2_irq_0();
|
||||
extern "C" void pic2_irq_1();
|
||||
extern "C" void pic2_irq_2();
|
||||
extern "C" void pic2_irq_3();
|
||||
extern "C" void pic2_irq_4();
|
||||
extern "C" void pic2_irq_5();
|
||||
extern "C" void pic2_irq_6();
|
||||
extern "C" void pic2_irq_7();
|
||||
|
||||
|
||||
void idt_set_descriptor(uint8_t vector, void *isr, uint8_t flags) {
|
||||
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;
|
||||
@@ -163,7 +163,7 @@ uint16_t pic_get_isr(void) {
|
||||
return __pic_get_irq_reg(PIC_READ_ISR);
|
||||
}
|
||||
|
||||
void pic1_irq_real_0(struct task_frame *frame) {
|
||||
extern "C" void pic1_irq_real_0(struct task_frame *frame) {
|
||||
timer_tick();
|
||||
assert2(frame->guard == IDT_GUARD, "IDT Guard wrong!");
|
||||
assert2((frame->ss == GDTSEL(gdt_data) || frame->ss == GDTSEL(gdt_data_user)), "SS wrong!");
|
||||
@@ -172,53 +172,53 @@ void pic1_irq_real_0(struct task_frame *frame) {
|
||||
assert2((frame->ss == GDTSEL(gdt_data) || frame->ss == GDTSEL(gdt_data_user)), "SS wrong!");
|
||||
PIC_sendEOI(0);
|
||||
}
|
||||
void pic1_irq_real_1() {
|
||||
extern "C" void pic1_irq_real_1() {
|
||||
PIC_sendEOI(1);
|
||||
}
|
||||
void pic1_irq_real_2() {
|
||||
extern "C" void pic1_irq_real_2() {
|
||||
_hcf();
|
||||
PIC_sendEOI(2);
|
||||
}
|
||||
void pic1_irq_real_3() {
|
||||
extern "C" void pic1_irq_real_3() {
|
||||
PIC_sendEOI(3);
|
||||
}
|
||||
void pic1_irq_real_4() {
|
||||
extern "C" void pic1_irq_real_4() {
|
||||
PIC_sendEOI(4);
|
||||
}
|
||||
void pic1_irq_real_5() {
|
||||
extern "C" void pic1_irq_real_5() {
|
||||
PIC_sendEOI(5);
|
||||
}
|
||||
void pic1_irq_real_6() {
|
||||
extern "C" void pic1_irq_real_6() {
|
||||
PIC_sendEOI(6);
|
||||
}
|
||||
void pic1_irq_real_7() {
|
||||
extern "C" void pic1_irq_real_7() {
|
||||
int irr = pic_get_irr();
|
||||
if (!(irr & 0x80)) return;
|
||||
PIC_sendEOI(7);
|
||||
}
|
||||
|
||||
void pic2_irq_real_0() {
|
||||
extern "C" void pic2_irq_real_0() {
|
||||
PIC_sendEOI(8);
|
||||
}
|
||||
void pic2_irq_real_1() {
|
||||
extern "C" void pic2_irq_real_1() {
|
||||
PIC_sendEOI(9);
|
||||
}
|
||||
void pic2_irq_real_2() {
|
||||
extern "C" void pic2_irq_real_2() {
|
||||
PIC_sendEOI(10);
|
||||
}
|
||||
void pic2_irq_real_3() {
|
||||
extern "C" void pic2_irq_real_3() {
|
||||
PIC_sendEOI(11);
|
||||
}
|
||||
void pic2_irq_real_4() {
|
||||
extern "C" void pic2_irq_real_4() {
|
||||
PIC_sendEOI(12);
|
||||
}
|
||||
void pic2_irq_real_5() {
|
||||
extern "C" void pic2_irq_real_5() {
|
||||
PIC_sendEOI(13);
|
||||
}
|
||||
void pic2_irq_real_6() {
|
||||
extern "C" void pic2_irq_real_6() {
|
||||
PIC_sendEOI(14);
|
||||
}
|
||||
void pic2_irq_real_7() {
|
||||
extern "C" void pic2_irq_real_7() {
|
||||
// Probaby wrong
|
||||
int irr = pic_get_irr();
|
||||
if (!(irr & (0x80 << 8))) {
|
||||
@@ -1,96 +0,0 @@
|
||||
#ifndef OS1_IDT_H
|
||||
#define OS1_IDT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.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 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_BUF_MASTER 0x0C /* Buffered mode/master */
|
||||
#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 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);
|
||||
uint16_t pic_get_irr(void);
|
||||
uint16_t pic_get_isr(void);
|
||||
|
||||
typedef struct {
|
||||
uint16_t isr_low; // The lower 16 bits of the ISR's address
|
||||
uint16_t kernel_cs; // The GDT segment selector that the CPU will load into CS before calling the ISR
|
||||
uint8_t ist; // The IST in the TSS that the CPU will load into RSP; set to zero for now
|
||||
uint8_t attributes; // Type and attributes; see the IDT page
|
||||
uint16_t isr_mid; // The higher 16 bits of the lower 32 bits of the ISR's address
|
||||
uint32_t isr_high; // The higher 32 bits of the ISR's address
|
||||
uint32_t reserved; // Set to zero
|
||||
} __attribute__((packed)) idt_entry_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t limit;
|
||||
uint64_t base;
|
||||
} __attribute__((packed)) idtr_t;
|
||||
|
||||
#define IDT_GUARD 0xdeadbe3fdeadb3efULL
|
||||
|
||||
// Assuming the compiler understands that this is pushed on the stack in the correct order
|
||||
struct task_frame {
|
||||
uint64_t guard;
|
||||
|
||||
char ssestate[512];
|
||||
|
||||
uint64_t r15;
|
||||
uint64_t r14;
|
||||
uint64_t r13;
|
||||
uint64_t r12;
|
||||
uint64_t r11;
|
||||
uint64_t r10;
|
||||
uint64_t r9;
|
||||
uint64_t r8;
|
||||
|
||||
uint64_t rdi;
|
||||
uint64_t rsi;
|
||||
uint64_t rbp;
|
||||
uint64_t rbx;
|
||||
uint64_t rdx;
|
||||
uint64_t rcx;
|
||||
uint64_t rax;
|
||||
|
||||
uint64_t ip;
|
||||
uint64_t cs;
|
||||
uint64_t flags;
|
||||
uint64_t sp;
|
||||
uint64_t ss;
|
||||
|
||||
} __attribute__((packed));
|
||||
|
||||
void exception_handler(void);
|
||||
|
||||
void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags);
|
||||
|
||||
void idt_init(void);
|
||||
|
||||
extern void* isr_stub_table[];
|
||||
|
||||
#endif
|
||||
96
src/arch/x86/idt.hpp
Normal file
96
src/arch/x86/idt.hpp
Normal file
@@ -0,0 +1,96 @@
|
||||
#ifndef OS1_IDT_H
|
||||
#define OS1_IDT_H
|
||||
|
||||
#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 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_BUF_MASTER 0x0C /* Buffered mode/master */
|
||||
#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 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);
|
||||
uint16_t pic_get_irr(void);
|
||||
uint16_t pic_get_isr(void);
|
||||
|
||||
typedef struct {
|
||||
uint16_t isr_low; // The lower 16 bits of the ISR's address
|
||||
uint16_t kernel_cs;// The GDT segment selector that the CPU will load into CS before calling the ISR
|
||||
uint8_t ist; // The IST in the TSS that the CPU will load into RSP; set to zero for now
|
||||
uint8_t attributes;// Type and attributes; see the IDT page
|
||||
uint16_t isr_mid; // The higher 16 bits of the lower 32 bits of the ISR's address
|
||||
uint32_t isr_high; // The higher 32 bits of the ISR's address
|
||||
uint32_t reserved; // Set to zero
|
||||
} __attribute__((packed)) idt_entry_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t limit;
|
||||
uint64_t base;
|
||||
} __attribute__((packed)) idtr_t;
|
||||
|
||||
#define IDT_GUARD 0xdeadbe3fdeadb3efULL
|
||||
|
||||
// Assuming the compiler understands that this is pushed on the stack in the correct order
|
||||
struct task_frame {
|
||||
uint64_t guard;
|
||||
|
||||
char ssestate[512];
|
||||
|
||||
uint64_t r15;
|
||||
uint64_t r14;
|
||||
uint64_t r13;
|
||||
uint64_t r12;
|
||||
uint64_t r11;
|
||||
uint64_t r10;
|
||||
uint64_t r9;
|
||||
uint64_t r8;
|
||||
|
||||
uint64_t rdi;
|
||||
uint64_t rsi;
|
||||
uint64_t rbp;
|
||||
uint64_t rbx;
|
||||
uint64_t rdx;
|
||||
uint64_t rcx;
|
||||
uint64_t rax;
|
||||
|
||||
uint64_t ip;
|
||||
uint64_t cs;
|
||||
uint64_t flags;
|
||||
uint64_t sp;
|
||||
uint64_t ss;
|
||||
|
||||
} __attribute__((packed));
|
||||
|
||||
extern "C" void exception_handler(void);
|
||||
|
||||
void idt_set_descriptor(uint8_t vector, void (*isr)(), uint8_t flags);
|
||||
|
||||
void idt_init(void);
|
||||
|
||||
extern void (*isr_stub_table[])();
|
||||
|
||||
#endif
|
||||
@@ -2,4 +2,4 @@
|
||||
// Created by Stepan Usatiuk on 12.08.2023.
|
||||
//
|
||||
|
||||
#include "io.h"
|
||||
#include "io.hpp"
|
||||
@@ -1,19 +1,18 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 13.08.2023.
|
||||
//
|
||||
#include <stdatomic.h>
|
||||
#include <stddef.h>
|
||||
#include <cstddef>
|
||||
|
||||
#include "globals.h"
|
||||
#include "kmem.h"
|
||||
#include "limine_fb.h"
|
||||
#include "memman.h"
|
||||
#include "misc.h"
|
||||
#include "mutex.h"
|
||||
#include "serial.h"
|
||||
#include "task.h"
|
||||
#include "timer.h"
|
||||
#include "tty.h"
|
||||
#include "globals.hpp"
|
||||
#include "kmem.hpp"
|
||||
#include "limine_fb.hpp"
|
||||
#include "memman.hpp"
|
||||
#include "misc.hpp"
|
||||
#include "mutex.hpp"
|
||||
#include "serial.hpp"
|
||||
#include "task.hpp"
|
||||
#include "timer.hpp"
|
||||
#include "tty.hpp"
|
||||
|
||||
void ktask();
|
||||
|
||||
@@ -27,7 +26,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 = framebuffer->address;
|
||||
uint32_t *fb_ptr = static_cast<uint32_t *>(framebuffer->address);
|
||||
fb_ptr[i * (framebuffer->pitch / 4) + i + 100] = c ? 0 : 0xFFFFFF;
|
||||
}
|
||||
}
|
||||
@@ -46,7 +45,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 = framebuffer->address;
|
||||
uint32_t *fb_ptr = static_cast<uint32_t *>(framebuffer->address);
|
||||
fb_ptr[i * (framebuffer->pitch / 4) + i] = c ? 0 : 0xFFFFFF;
|
||||
}
|
||||
}
|
||||
@@ -65,7 +64,7 @@ void freeprinter() {
|
||||
}
|
||||
}
|
||||
|
||||
static struct Mutex testmutex = DefaultMutex;
|
||||
static struct Mutex testmutex;
|
||||
|
||||
void mtest1() {
|
||||
m_lock(&testmutex);
|
||||
@@ -95,7 +94,7 @@ void mtest3() {
|
||||
}
|
||||
|
||||
void stress() {
|
||||
static atomic_int i = 0;
|
||||
static std::atomic<int> i = 0;
|
||||
int curi = i++;
|
||||
if (curi > 1500) remove_self();
|
||||
|
||||
@@ -131,10 +130,16 @@ void dummy_task() {
|
||||
}
|
||||
}
|
||||
|
||||
extern void (*ctors_begin)();
|
||||
extern void (*ctors_end)();
|
||||
|
||||
void kmain() {
|
||||
struct tty_funcs serial_tty = {.putchar = write_serial};
|
||||
add_tty(serial_tty);
|
||||
|
||||
for (void (*ctor)() = ctors_begin; ctor < ctors_end; ctor++)
|
||||
(*ctor)();
|
||||
|
||||
init_timer();
|
||||
new_ktask(ktask_main, "ktask_main");
|
||||
new_ktask(dummy_task, "dummy");
|
||||
@@ -1,22 +1,22 @@
|
||||
#include "kmem.h"
|
||||
#include "kmem.hpp"
|
||||
|
||||
#include "globals.h"
|
||||
#include "memman.h"
|
||||
#include "mutex.h"
|
||||
#include "paging.h"
|
||||
#include "serial.h"
|
||||
#include "task.h"
|
||||
#include "globals.hpp"
|
||||
#include "memman.hpp"
|
||||
#include "mutex.hpp"
|
||||
#include "paging.hpp"
|
||||
#include "serial.hpp"
|
||||
#include "task.hpp"
|
||||
|
||||
struct HeapEntry *KERN_HeapBegin;
|
||||
uintptr_t KERN_HeapEnd;// Past the end
|
||||
|
||||
static bool initialized = false;
|
||||
|
||||
static struct Mutex kmem_lock = DefaultMutex;
|
||||
static struct Mutex kmem_lock;
|
||||
static char kmem_lock_tasklist[256];//FIXME:
|
||||
|
||||
void init_kern_heap() {
|
||||
KERN_HeapBegin = get4k();
|
||||
KERN_HeapBegin = static_cast<HeapEntry *>(get4k());
|
||||
KERN_HeapBegin->magic = KERN_HeapMagicFree;
|
||||
KERN_HeapBegin->len = 4096 - (sizeof(struct HeapEntry));
|
||||
KERN_HeapBegin->next = NULL;
|
||||
@@ -44,7 +44,7 @@ struct HeapEntry *split_entry(struct HeapEntry *what, size_t n) {
|
||||
assert(kmem_lock.owner == cur_task());
|
||||
|
||||
assert2(what->len > (n + sizeof(struct HeapEntry)), "Trying to split a heap entry that's too small!");
|
||||
struct HeapEntry *new_entry = (((void *) what) + sizeof(struct HeapEntry) + n);
|
||||
struct HeapEntry *new_entry = (struct HeapEntry *) (((void *) what) + sizeof(struct HeapEntry) + n);
|
||||
|
||||
new_entry->magic = KERN_HeapMagicFree;
|
||||
new_entry->next = what->next;
|
||||
@@ -242,7 +242,7 @@ void kfree(void *addr) {
|
||||
assert(initialized);
|
||||
m_lock(&kmem_lock);
|
||||
|
||||
struct HeapEntry *freed = addr - (sizeof(struct HeapEntry));
|
||||
struct HeapEntry *freed = (struct HeapEntry *) (addr - (sizeof(struct HeapEntry)));
|
||||
struct HeapEntry *entry = KERN_HeapBegin;
|
||||
assert2(freed->magic == KERN_HeapMagicTaken, "Bad free!");
|
||||
assert2(freed->next == NULL, "Bad free!");
|
||||
@@ -267,15 +267,15 @@ void kfree(void *addr) {
|
||||
void *krealloc(void *addr, size_t newsize) {
|
||||
assert(initialized);
|
||||
|
||||
struct HeapEntry *info = addr - (sizeof(struct HeapEntry));
|
||||
struct HeapEntry *info = (struct HeapEntry *) (addr - (sizeof(struct HeapEntry)));
|
||||
assert2(info->magic == KERN_HeapMagicTaken, "Bad realloc!");
|
||||
|
||||
void *new = kmalloc(newsize);
|
||||
void *newt = kmalloc(newsize);
|
||||
|
||||
memcpy(new, addr, newsize > info->len ? info->len : newsize);
|
||||
memcpy(newt, addr, newsize > info->len ? info->len : newsize);
|
||||
kfree(addr);
|
||||
|
||||
return new;
|
||||
return newt;
|
||||
}
|
||||
|
||||
void *memcpy(void *dest, const void *src, size_t n) {
|
||||
@@ -2,11 +2,11 @@
|
||||
// Created by Stepan Usatiuk on 12.08.2023.
|
||||
//
|
||||
|
||||
#include "limine_fb.h"
|
||||
#include "limine_fb.hpp"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "kmem.h"
|
||||
#include "kmem.hpp"
|
||||
|
||||
static volatile struct limine_framebuffer_request framebuffer_request = {
|
||||
.id = LIMINE_FRAMEBUFFER_REQUEST,
|
||||
@@ -19,7 +19,7 @@ struct {
|
||||
uint64_t len;
|
||||
} framebufferAddrs[10];
|
||||
|
||||
void limine_fb_save_response(struct AddressSpace* boot_address_space) {
|
||||
void limine_fb_save_response(struct AddressSpace *boot_address_space) {
|
||||
if (framebuffer_request.response == NULL || framebuffer_request.response->framebuffer_count < 1) {
|
||||
framebuffer_count = 0;
|
||||
return;
|
||||
@@ -33,7 +33,7 @@ void limine_fb_save_response(struct AddressSpace* boot_address_space) {
|
||||
}
|
||||
}
|
||||
|
||||
void limine_fb_remap(struct AddressSpace* space) {
|
||||
void limine_fb_remap(struct AddressSpace *space) {
|
||||
for (int i = 0; i < framebuffer_count; i++) {
|
||||
void *base = framebuffers[i].address;
|
||||
void *realbase = framebufferAddrs[i].base;
|
||||
@@ -7,10 +7,10 @@
|
||||
|
||||
#include "limine.h"
|
||||
|
||||
#include "paging.h"
|
||||
#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 struct limine_framebuffer framebuffers[10];
|
||||
@@ -1,29 +0,0 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 12.08.2023.
|
||||
//
|
||||
|
||||
#include "limine_mm.h"
|
||||
|
||||
#include "kmem.h"
|
||||
#include "limine.h"
|
||||
|
||||
static volatile struct limine_memmap_request memmap_request = {
|
||||
.id = LIMINE_MEMMAP_REQUEST,
|
||||
.revision = 0};
|
||||
|
||||
unsigned int limine_mm_count;
|
||||
struct limine_memmap_entry limine_mm_entries[LIMINE_MM_MAX];
|
||||
unsigned int limine_mm_overflow;
|
||||
|
||||
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_overflow = 1;
|
||||
} else {
|
||||
limine_mm_overflow = 0;
|
||||
}
|
||||
for (int i = 0; i < limine_mm_count; i++) {
|
||||
memcpy(&limine_mm_entries[i], memmap_request.response->entries[i], sizeof(struct limine_memmap_entry));
|
||||
}
|
||||
}
|
||||
29
src/arch/x86/limine_mm.cpp
Normal file
29
src/arch/x86/limine_mm.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 12.08.2023.
|
||||
//
|
||||
|
||||
#include "limine_mm.hpp"
|
||||
|
||||
#include "kmem.hpp"
|
||||
#include "limine.h"
|
||||
|
||||
static volatile struct limine_memmap_request memmap_request = {
|
||||
.id = LIMINE_MEMMAP_REQUEST,
|
||||
.revision = 0};
|
||||
|
||||
unsigned int limine_mm_count;
|
||||
struct limine_memmap_entry limine_mm_entries[LIMINE_MM_MAX];
|
||||
unsigned int limine_mm_overflow;
|
||||
|
||||
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_overflow = 1;
|
||||
} else {
|
||||
limine_mm_overflow = 0;
|
||||
}
|
||||
for (int i = 0; i < limine_mm_count; i++) {
|
||||
memcpy(&limine_mm_entries[i], memmap_request.response->entries[i], sizeof(struct limine_memmap_entry));
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,11 @@ SECTIONS
|
||||
. += CONSTANT(MAXPAGESIZE);
|
||||
|
||||
.rodata : {
|
||||
ctors_begin = .;
|
||||
*(.ctors)
|
||||
*(.init_array)
|
||||
ctors_end = .;
|
||||
|
||||
*(.rodata .rodata.*)
|
||||
} :rodata
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
// Created by Stepan Usatiuk on 12.08.2023.
|
||||
//
|
||||
|
||||
#include "memman.h"
|
||||
#include "misc.h"
|
||||
#include "mutex.h"
|
||||
#include "paging.h"
|
||||
#include "serial.h"
|
||||
#include "memman.hpp"
|
||||
#include "misc.hpp"
|
||||
#include "mutex.hpp"
|
||||
#include "paging.hpp"
|
||||
#include "serial.hpp"
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// Created by Stepan Usatiuk on 13.08.2023.
|
||||
//
|
||||
|
||||
void _hcf() {
|
||||
extern "C" void _hcf() {
|
||||
while (1)
|
||||
asm volatile("cli; hlt");
|
||||
}
|
||||
@@ -3,10 +3,11 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void _sse_setup();
|
||||
void _hcf();
|
||||
extern "C" void _sse_setup();
|
||||
extern "C" void _hcf();
|
||||
|
||||
#define barrier() __asm__ __volatile__ ("" ::: "memory");
|
||||
#define barrier() __asm__ __volatile__("" :: \
|
||||
: "memory");
|
||||
|
||||
static inline uint64_t *get_cr3() {
|
||||
uint64_t *cr3;
|
||||
@@ -52,7 +53,6 @@ static inline void irqrestore(unsigned long flags) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *itoa(int value, char *str, int base);
|
||||
|
||||
#endif
|
||||
@@ -2,24 +2,24 @@
|
||||
// Created by Stepan Usatiuk on 09.08.2023.
|
||||
//
|
||||
|
||||
#include "paging.h"
|
||||
#include "paging.hpp"
|
||||
#include "limine.h"
|
||||
#include "memman.h"
|
||||
#include "misc.h"
|
||||
#include "serial.h"
|
||||
#include "memman.hpp"
|
||||
#include "misc.hpp"
|
||||
#include "serial.hpp"
|
||||
|
||||
struct AddressSpace *KERN_AddressSpace;
|
||||
|
||||
int init_addr_space(struct AddressSpace *space) {
|
||||
assert2(space != NULL, "Got null!");
|
||||
space->PML4 = get4k();
|
||||
space->PML4 = static_cast<uint64_t *>(get4k());
|
||||
if (space->PML4 == NULL) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Returns a free page frame in HHDM
|
||||
uint64_t *get_free_frame() {
|
||||
uint64_t *res = get4k();
|
||||
uint64_t *res = static_cast<uint64_t *>(get4k());
|
||||
if (res)
|
||||
for (int j = 0; j < 512; j++)
|
||||
res[j] = 0;
|
||||
@@ -40,6 +40,6 @@ void *virt2real(void *virt, struct AddressSpace *space);
|
||||
|
||||
void map_hddm(uint64_t *pml4);
|
||||
|
||||
void _tlb_flush();
|
||||
extern "C" void _tlb_flush();
|
||||
|
||||
#endif//OS1_PAGING_H
|
||||
@@ -2,12 +2,12 @@
|
||||
// Created by Stepan Usatiuk on 12.08.2023.
|
||||
//
|
||||
|
||||
#include "serial.h"
|
||||
#include "serial.hpp"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "io.h"
|
||||
#include "task.h"
|
||||
#include "io.hpp"
|
||||
#include "task.hpp"
|
||||
|
||||
#define PORT 0x3f8// COM1
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#ifndef OS1_SERIAL_H
|
||||
#define OS1_SERIAL_H
|
||||
|
||||
#include "misc.h"
|
||||
#include "misc.hpp"
|
||||
|
||||
int init_serial();
|
||||
|
||||
@@ -15,14 +15,14 @@ char read_serial();
|
||||
int is_transmit_empty();
|
||||
void write_serial(char a);
|
||||
void writestr(const char *a);
|
||||
|
||||
extern "C" {
|
||||
static inline void _assert2(int val, const char *msg) {
|
||||
if (!val) {
|
||||
writestr(msg);
|
||||
_hcf();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#define assert2(x, y) _assert2(x, y)
|
||||
#define assert(x) _assert2(x, "Assertion failed")
|
||||
|
||||
@@ -2,16 +2,16 @@
|
||||
// Created by Stepan Usatiuk on 18.08.2023.
|
||||
//
|
||||
|
||||
#include "task.h"
|
||||
#include "cv.h"
|
||||
#include "gdt.h"
|
||||
#include "kmem.h"
|
||||
#include "misc.h"
|
||||
#include "mutex.h"
|
||||
#include "paging.h"
|
||||
#include "serial.h"
|
||||
#include "timer.h"
|
||||
#include "tty.h"
|
||||
#include "task.hpp"
|
||||
#include "cv.hpp"
|
||||
#include "gdt.hpp"
|
||||
#include "kmem.hpp"
|
||||
#include "misc.hpp"
|
||||
#include "mutex.hpp"
|
||||
#include "paging.hpp"
|
||||
#include "serial.hpp"
|
||||
#include "timer.hpp"
|
||||
#include "tty.hpp"
|
||||
|
||||
void sanity_check_frame(struct task_frame *cur_frame) {
|
||||
assert2((void *) cur_frame->ip != NULL, "Sanity check");
|
||||
@@ -36,16 +36,16 @@ struct TaskListNode *RunningTask;
|
||||
struct TaskList NextTasks;
|
||||
|
||||
// New tasks
|
||||
struct Mutex NewTasks_lock = DefaultMutex;
|
||||
struct Mutex NewTasks_lock;
|
||||
struct TaskList NewTasks;
|
||||
|
||||
// Unblocked tasks
|
||||
struct Mutex UnblockedTasks_lock = DefaultMutex;
|
||||
struct Mutex UnblockedTasks_lock;
|
||||
struct TaskList UnblockedTasks;
|
||||
|
||||
// Task freer
|
||||
struct Mutex TasksToFree_lock = DefaultMutex;
|
||||
struct CV TasksToFree_cv = DefaultCV;
|
||||
struct Mutex TasksToFree_lock;
|
||||
struct CV TasksToFree_cv;
|
||||
struct TaskList TasksToFree;
|
||||
struct TaskList TasksToFreeTemp;
|
||||
|
||||
@@ -53,7 +53,7 @@ struct TaskList TasksToFreeTemp;
|
||||
//struct Mutex WaitingTasks_lock = DefaultMutex;
|
||||
struct TaskList WaitingTasks;
|
||||
|
||||
static volatile atomic_bool initialized = false;
|
||||
static std::atomic<bool> initialized = false;
|
||||
|
||||
static void free_task(struct Task *t) {
|
||||
kfree(t->stack);
|
||||
@@ -66,7 +66,7 @@ static void free_task_list_node(struct TaskListNode *t) {
|
||||
}
|
||||
|
||||
static struct TaskListNode *new_task_list_node() {
|
||||
struct TaskListNode *ret = kmalloc(sizeof(struct TaskListNode));
|
||||
struct TaskListNode *ret = static_cast<TaskListNode *>(kmalloc(sizeof(struct TaskListNode)));
|
||||
ret->task = NULL;
|
||||
ret->next = NULL;
|
||||
return ret;
|
||||
@@ -153,7 +153,7 @@ static struct TaskListNode *pop_front_node(struct TaskList *list) {
|
||||
}
|
||||
|
||||
|
||||
_Noreturn static void task_freer() {
|
||||
static void task_freer() {
|
||||
while (true) {
|
||||
m_lock(&TasksToFree_lock);
|
||||
cv_wait(&TasksToFree_lock, &TasksToFree_cv);
|
||||
@@ -165,29 +165,29 @@ _Noreturn static void task_freer() {
|
||||
}
|
||||
}
|
||||
|
||||
struct Task *new_ktask(void(*fn), char *name) {
|
||||
struct Task *new = kmalloc(sizeof(struct Task));
|
||||
new->stack = kmalloc(TASK_SS);
|
||||
new->name = kmalloc(strlen(name) + 1);
|
||||
strcpy(name, new->name);
|
||||
struct Task *new_ktask(void (*fn)(), char *name) {
|
||||
struct Task *newt = static_cast<Task *>(kmalloc(sizeof(struct Task)));
|
||||
newt->stack = static_cast<uint64_t *>(kmalloc(TASK_SS));
|
||||
newt->name = static_cast<char *>(kmalloc(strlen(name) + 1));
|
||||
strcpy(name, newt->name);
|
||||
|
||||
new->frame.sp = ((uint64_t) (&((void *) new->stack)[TASK_SS - 1]) & (~0xFULL));// Ensure 16byte alignment
|
||||
new->frame.ip = (uint64_t) fn;
|
||||
new->frame.cs = GDTSEL(gdt_code);
|
||||
new->frame.ss = GDTSEL(gdt_data);
|
||||
for (int i = 0; i < 512; i++) new->frame.ssestate[i] = 0;
|
||||
new->frame.flags = flags();
|
||||
new->frame.guard = IDT_GUARD;
|
||||
new->addressSpace = KERN_AddressSpace;
|
||||
new->state = TS_RUNNING;
|
||||
new->mode = TASKMODE_KERN;
|
||||
newt->frame.sp = ((((uintptr_t) newt->stack) + TASK_SS - 1) & (~0xFULL));// Ensure 16byte alignment
|
||||
newt->frame.ip = (uint64_t) fn;
|
||||
newt->frame.cs = GDTSEL(gdt_code);
|
||||
newt->frame.ss = GDTSEL(gdt_data);
|
||||
for (int i = 0; i < 512; i++) newt->frame.ssestate[i] = 0;
|
||||
newt->frame.flags = flags();
|
||||
newt->frame.guard = IDT_GUARD;
|
||||
newt->addressSpace = KERN_AddressSpace;
|
||||
newt->state = TS_RUNNING;
|
||||
newt->mode = TASKMODE_KERN;
|
||||
|
||||
sanity_check_frame(&new->frame);
|
||||
sanity_check_frame(&newt->frame);
|
||||
|
||||
m_lock(&NewTasks_lock);
|
||||
append_task(&NewTasks, new);
|
||||
append_task(&NewTasks, newt);
|
||||
m_unlock(&NewTasks_lock);
|
||||
return new;
|
||||
return newt;
|
||||
}
|
||||
|
||||
void init_tasks() {
|
||||
@@ -218,7 +218,7 @@ void yield_self() {
|
||||
}
|
||||
|
||||
|
||||
void switch_task(struct task_frame *cur_frame) {
|
||||
extern "C" void switch_task(struct task_frame *cur_frame) {
|
||||
if (!atomic_load(&initialized)) return;
|
||||
sanity_check_frame(cur_frame);
|
||||
|
||||
@@ -316,7 +316,7 @@ void switch_task_int(struct task_frame *cur_frame) {
|
||||
|
||||
void wait_m_on_self(struct Mutex *m) {
|
||||
if (!m->waiters) {
|
||||
m->waiters = kmalloc(sizeof(struct TaskList));
|
||||
m->waiters = static_cast<TaskList *>(kmalloc(sizeof(struct TaskList)));
|
||||
m->waiters->cur = NULL;
|
||||
m->waiters->last = NULL;
|
||||
}
|
||||
@@ -327,16 +327,16 @@ void wait_m_on_self(struct Mutex *m) {
|
||||
}
|
||||
|
||||
void m_unlock_sched_hook(struct Mutex *m) {
|
||||
struct TaskListNode *new = NULL;
|
||||
struct TaskListNode *newt = NULL;
|
||||
|
||||
NO_INT(if (m->waiters) {
|
||||
new = pop_front_node(m->waiters);
|
||||
newt = pop_front_node(m->waiters);
|
||||
})
|
||||
|
||||
if (new) {
|
||||
new->task->state = TS_RUNNING;
|
||||
if (newt) {
|
||||
newt->task->state = TS_RUNNING;
|
||||
m_spin_lock(&UnblockedTasks_lock);
|
||||
append_task_node(&UnblockedTasks, new);
|
||||
append_task_node(&UnblockedTasks, newt);
|
||||
m_unlock(&UnblockedTasks_lock);
|
||||
}
|
||||
}
|
||||
@@ -344,7 +344,7 @@ void m_unlock_sched_hook(struct Mutex *m) {
|
||||
|
||||
void wait_cv_on_self(struct CV *cv) {
|
||||
if (!cv->waiters) {
|
||||
cv->waiters = kmalloc(sizeof(struct TaskList));
|
||||
cv->waiters = static_cast<TaskList *>(kmalloc(sizeof(struct TaskList)));
|
||||
cv->waiters->cur = NULL;
|
||||
cv->waiters->last = NULL;
|
||||
}
|
||||
@@ -355,19 +355,19 @@ void wait_cv_on_self(struct CV *cv) {
|
||||
}
|
||||
|
||||
void cv_unlock_sched_hook(struct CV *cv, int who) {
|
||||
struct TaskListNode *new = NULL;
|
||||
struct TaskListNode *newt = NULL;
|
||||
do {
|
||||
NO_INT(if (cv->waiters) {
|
||||
new = pop_front_node(cv->waiters);
|
||||
newt = pop_front_node(cv->waiters);
|
||||
})
|
||||
|
||||
if (new) {
|
||||
new->task->state = TS_RUNNING;
|
||||
if (newt) {
|
||||
newt->task->state = TS_RUNNING;
|
||||
m_spin_lock(&UnblockedTasks_lock);
|
||||
append_task_node(&UnblockedTasks, new);
|
||||
append_task_node(&UnblockedTasks, newt);
|
||||
m_unlock(&UnblockedTasks_lock);
|
||||
}
|
||||
} while (new && (who == CV_NOTIFY_ALL));
|
||||
} while (newt && (who == CV_NOTIFY_ALL));
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "idt.h"
|
||||
#include "idt.hpp"
|
||||
|
||||
#define TASK_SS 16384
|
||||
|
||||
@@ -39,17 +39,17 @@ struct Task {
|
||||
struct Task *cur_task();
|
||||
|
||||
void init_tasks();
|
||||
struct Task *new_ktask(void(*fn), char *name);
|
||||
struct Task *new_ktask(void (*fn)(), char *name);
|
||||
void remove_self();
|
||||
void sleep_self(uint64_t diff);
|
||||
void switch_task(struct task_frame *cur_frame);
|
||||
extern "C" void switch_task(struct task_frame *cur_frame);
|
||||
void switch_task_int(struct task_frame *cur_frame);
|
||||
void wait_m_on_self(struct Mutex *m);
|
||||
void m_unlock_sched_hook(struct Mutex *m);
|
||||
void wait_cv_on_self(struct CV *cv);
|
||||
void stop_waiting_on(struct Mutex *m);
|
||||
void yield_self();
|
||||
void _yield_self_kern();// Expects the caller to save interrupt state
|
||||
extern "C" void _yield_self_kern();// Expects the caller to save interrupt state
|
||||
void cv_unlock_sched_hook(struct CV *cv, int who);
|
||||
|
||||
#endif//OS1_TASK_H
|
||||
@@ -2,10 +2,10 @@
|
||||
// Created by Stepan Usatiuk on 14.08.2023.
|
||||
//
|
||||
|
||||
#include "timer.h"
|
||||
#include "timer.hpp"
|
||||
|
||||
#include "idt.h"
|
||||
#include "io.h"
|
||||
#include "idt.hpp"
|
||||
#include "io.hpp"
|
||||
|
||||
volatile uint64_t ticks;
|
||||
volatile uint64_t micros;
|
||||
@@ -2,14 +2,14 @@
|
||||
// Created by Stepan Usatiuk on 25.08.2023.
|
||||
//
|
||||
|
||||
#include "tty.h"
|
||||
#include "tty.hpp"
|
||||
|
||||
#include "kmem.h"
|
||||
#include "mutex.h"
|
||||
#include "serial.h"
|
||||
#include "kmem.hpp"
|
||||
#include "mutex.hpp"
|
||||
#include "serial.hpp"
|
||||
|
||||
static unsigned ttyNum = 0;
|
||||
static struct Mutex ttysMutex = DefaultMutex;
|
||||
static struct Mutex ttysMutex;
|
||||
|
||||
struct ttys {
|
||||
unsigned num;
|
||||
@@ -18,16 +18,16 @@ struct ttys {
|
||||
|
||||
struct ttys ttys = {.num = 0};
|
||||
|
||||
unsigned add_tty(struct tty_funcs funcs) {
|
||||
void add_tty(struct tty_funcs funcs) {
|
||||
m_lock(&ttysMutex);
|
||||
|
||||
if (ttyNum >= ttys.num) {
|
||||
if (ttys.num == 0) {
|
||||
ttys.ttys = kmalloc(sizeof(struct ttys) + sizeof(struct tty));
|
||||
ttys.ttys = static_cast<tty *>(kmalloc(sizeof(struct ttys) + sizeof(struct tty)));
|
||||
ttys.num = 1;
|
||||
} else {
|
||||
ttys.num *= 2;
|
||||
ttys.ttys = krealloc(ttys.ttys, sizeof(struct ttys) + sizeof(struct tty) * ttys.num);
|
||||
ttys.ttys = static_cast<tty *>(krealloc(ttys.ttys, sizeof(struct ttys) + sizeof(struct tty) * ttys.num));
|
||||
}
|
||||
assert2(ttys.ttys != NULL, "Couldn't allocate memory for ttys!");
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
#ifndef OS1_TTY_H
|
||||
#define OS1_TTY_H
|
||||
|
||||
#include "mutex.h"
|
||||
#include "mutex.hpp"
|
||||
#include <stdint.h>
|
||||
|
||||
struct tty_funcs {
|
||||
@@ -18,7 +18,7 @@ struct tty {
|
||||
struct tty_funcs funcs;
|
||||
};
|
||||
|
||||
unsigned add_tty(struct tty_funcs);
|
||||
void add_tty(struct tty_funcs);
|
||||
void tty_putchar(struct tty *tty, char c);
|
||||
void tty_putstr(struct tty *tty, const char *str);
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
target_include_directories(kernel.elf PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
target_sources(kernel.elf PRIVATE mutex.c cv.c)
|
||||
target_sources(kernel.elf PRIVATE mutex.cpp cv.cpp)
|
||||
@@ -2,11 +2,11 @@
|
||||
// Created by Stepan Usatiuk on 20.08.2023.
|
||||
//
|
||||
|
||||
#include "cv.h"
|
||||
#include "cv.hpp"
|
||||
|
||||
#include "mutex.h"
|
||||
#include "serial.h"
|
||||
#include "task.h"
|
||||
#include "mutex.hpp"
|
||||
#include "serial.hpp"
|
||||
#include "task.hpp"
|
||||
|
||||
void cv_wait(struct Mutex *m, struct CV *cv) {
|
||||
m_unlock(m);
|
||||
@@ -5,8 +5,8 @@
|
||||
#ifndef OS1_CV_H
|
||||
#define OS1_CV_H
|
||||
|
||||
#include <stdatomic.h>
|
||||
#include <stddef.h>
|
||||
#include <atomic>
|
||||
#include <cstddef>
|
||||
|
||||
#if !(ATOMIC_INT_LOCK_FREE == 2)
|
||||
#error Atomic int isnt lock free!
|
||||
@@ -21,14 +21,10 @@ enum CV_NOTIFY {
|
||||
};
|
||||
|
||||
struct CV {
|
||||
atomic_int_fast8_t notified;
|
||||
std::atomic<int> notified;
|
||||
struct TaskList *waiters;
|
||||
};
|
||||
|
||||
static const struct CV DefaultCV = {
|
||||
.notified = ATOMIC_VAR_INIT(CV_NOTIFY_NONE),
|
||||
.waiters = NULL};
|
||||
|
||||
void cv_wait(struct Mutex *m, struct CV *cv);
|
||||
void cv_notify_one(struct CV *cv);
|
||||
void cv_notify_all(struct CV *cv);
|
||||
@@ -2,10 +2,10 @@
|
||||
// Created by Stepan Usatiuk on 20.08.2023.
|
||||
//
|
||||
|
||||
#include "mutex.h"
|
||||
#include "serial.h"
|
||||
#include "task.h"
|
||||
#include "timer.h"
|
||||
#include "mutex.hpp"
|
||||
#include "serial.hpp"
|
||||
#include "task.hpp"
|
||||
#include "timer.hpp"
|
||||
|
||||
void m_init(struct Mutex *m) {
|
||||
atomic_init(&m->locked, false);
|
||||
@@ -15,8 +15,8 @@ void m_init(struct Mutex *m) {
|
||||
}
|
||||
|
||||
bool m_try_lock(struct Mutex *m) {
|
||||
volatile atomic_bool expected = ATOMIC_VAR_INIT(false);
|
||||
if (!atomic_compare_exchange_strong(&m->locked, &expected, true)) {
|
||||
bool expected = false;
|
||||
if (!m->locked.compare_exchange_strong(expected, true)) {
|
||||
return false;
|
||||
}
|
||||
m->owner = cur_task();
|
||||
@@ -64,8 +64,8 @@ void m_lock(struct Mutex *m) {
|
||||
}
|
||||
|
||||
void m_unlock(struct Mutex *m) {
|
||||
volatile atomic_bool expected = ATOMIC_VAR_INIT(true);
|
||||
if (!atomic_compare_exchange_strong(&m->locked, &expected, false))
|
||||
bool expected = true;
|
||||
if (!m->locked.compare_exchange_strong(expected, false))
|
||||
writestr("Unlocking an unlocked mutex!\n");
|
||||
m_unlock_sched_hook(m);
|
||||
}
|
||||
@@ -5,27 +5,18 @@
|
||||
#ifndef OS1_MUTEX_H
|
||||
#define OS1_MUTEX_H
|
||||
|
||||
#include <stdatomic.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <atomic>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#if !(ATOMIC_BOOL_LOCK_FREE == 2)
|
||||
#error Atomic bool isnt lock free!
|
||||
#endif
|
||||
|
||||
struct Mutex {
|
||||
volatile atomic_bool locked;
|
||||
std::atomic<bool> locked;
|
||||
struct TaskList *waiters;
|
||||
struct Task *owner;
|
||||
uint8_t spin_success;
|
||||
};
|
||||
|
||||
static const struct Mutex DefaultMutex = {
|
||||
.locked = ATOMIC_VAR_INIT(false),
|
||||
.spin_success = 150,
|
||||
.waiters = NULL};
|
||||
|
||||
void m_init(struct Mutex *m);
|
||||
void m_lock(struct Mutex *m);
|
||||
void m_spin_lock(struct Mutex *m);
|
||||
Reference in New Issue
Block a user