From 54a5ee720f086063d38279824c1a2441a0b49763 Mon Sep 17 00:00:00 2001 From: Patrick Wuttke Date: Mon, 29 Jan 2024 18:14:20 +0100 Subject: [PATCH] Some restructuring. --- targets/_any/SConscript | 52 +----- targets/_any/include/os/interrupt.hpp | 47 ------ targets/_any/kernel/SConscript | 57 +++++++ targets/_any/{ => kernel}/include/os/cpu.hpp | 0 targets/_any/{ => kernel}/include/os/draw.hpp | 0 targets/_any/kernel/include/os/interrupt.hpp | 149 ++++++++++++++++++ .../_any/{ => kernel}/include/os/memory.hpp | 0 .../_any/{ => kernel}/include/os/panic.hpp | 0 targets/_any/{ => kernel}/include/os/port.hpp | 0 .../_any/{ => kernel}/include/os/segments.hpp | 0 .../_any/{ => kernel}/include/os/serial.hpp | 0 .../_any/{ => kernel}/include/os/syscall.hpp | 0 .../include/os/tools/printf_helper.hpp | 0 .../include/os/tools/ringbuffer.hpp | 0 targets/_any/{ => kernel}/include/os/tty.hpp | 0 .../include}/resources/.gitignore | 0 targets/_any/{src/os => kernel/src}/draw.cpp | 0 targets/_any/{ => kernel}/src/drivers/pci.cpp | 0 targets/_any/{ => kernel}/src/drivers/pic.cpp | 0 targets/_any/{ => kernel}/src/drivers/ps2.cpp | 0 targets/_any/{ => kernel}/src/drivers/usb.cpp | 0 .../_any/{src/os => kernel/src}/interrupt.cpp | 0 .../_any/{src/os => kernel/src}/memory.cpp | 0 targets/_any/{src/os => kernel/src}/panic.cpp | 0 .../os => kernel/src}/resources/.gitignore | 0 .../os => kernel/src}/resources/lat9-08.psf | Bin .../_any/{src/os => kernel/src}/syscall.cpp | 0 targets/_any/{src/os => kernel/src}/tty.cpp | 2 +- targets/_any/src/cstdlib/stdio.cpp | 20 ++- targets/x86_64/SConscript | 3 +- targets/x86_64/src/kernel/boot.s | 2 +- targets/x86_64/src/kernel/startup.cpp | 59 +------ targets/x86_64/src/kernel/x86_64.hpp | 29 ---- 33 files changed, 230 insertions(+), 190 deletions(-) delete mode 100644 targets/_any/include/os/interrupt.hpp create mode 100644 targets/_any/kernel/SConscript rename targets/_any/{ => kernel}/include/os/cpu.hpp (100%) rename targets/_any/{ => kernel}/include/os/draw.hpp (100%) create mode 100644 targets/_any/kernel/include/os/interrupt.hpp rename targets/_any/{ => kernel}/include/os/memory.hpp (100%) rename targets/_any/{ => kernel}/include/os/panic.hpp (100%) rename targets/_any/{ => kernel}/include/os/port.hpp (100%) rename targets/_any/{ => kernel}/include/os/segments.hpp (100%) rename targets/_any/{ => kernel}/include/os/serial.hpp (100%) rename targets/_any/{ => kernel}/include/os/syscall.hpp (100%) rename targets/_any/{ => kernel}/include/os/tools/printf_helper.hpp (100%) rename targets/_any/{ => kernel}/include/os/tools/ringbuffer.hpp (100%) rename targets/_any/{ => kernel}/include/os/tty.hpp (100%) rename targets/_any/{include/os => kernel/include}/resources/.gitignore (100%) rename targets/_any/{src/os => kernel/src}/draw.cpp (100%) rename targets/_any/{ => kernel}/src/drivers/pci.cpp (100%) rename targets/_any/{ => kernel}/src/drivers/pic.cpp (100%) rename targets/_any/{ => kernel}/src/drivers/ps2.cpp (100%) rename targets/_any/{ => kernel}/src/drivers/usb.cpp (100%) rename targets/_any/{src/os => kernel/src}/interrupt.cpp (100%) rename targets/_any/{src/os => kernel/src}/memory.cpp (100%) rename targets/_any/{src/os => kernel/src}/panic.cpp (100%) rename targets/_any/{src/os => kernel/src}/resources/.gitignore (100%) rename targets/_any/{src/os => kernel/src}/resources/lat9-08.psf (100%) rename targets/_any/{src/os => kernel/src}/syscall.cpp (100%) rename targets/_any/{src/os => kernel/src}/tty.cpp (99%) diff --git a/targets/_any/SConscript b/targets/_any/SConscript index c0c4c32..6ed97df 100644 --- a/targets/_any/SConscript +++ b/targets/_any/SConscript @@ -1,66 +1,18 @@ Import('env') -def _resource(env, res, symbol): - def _generate_s(target, source, env): - with open(target[0].abspath, 'w') as f: - f.write(f''' - .section .rodata - .global {symbol} - .type {symbol} @object - - .section .rodata - .global {symbol}_SIZE - .type {symbol}_SIZE @object -{symbol}: - .incbin "{res}" -{symbol}_END: -{symbol}_SIZE: - .int {symbol}_END - {symbol} -''') - with open(target[1].abspath, 'w') as f: - f.write(f''' -#pragma once - -#include - -extern "C" -{{ -extern const uint8_t {symbol}[]; -extern const unsigned {symbol}_SIZE; -}} - -''') - env.Command([f'{res}.s', f'{res}.hpp'.replace('src/', 'include/')], res, action = _generate_s) -env.AddMethod(_resource, 'Resource') - -isr_sources = Split(''' - src/drivers/pic.cpp - src/drivers/ps2.cpp - src/os/interrupt.cpp -''') any_target_sources = Split(''' src/app/main.cpp - src/drivers/pci.cpp - src/drivers/usb.cpp - src/libs/psf.cpp - src/os/draw.cpp - src/os/memory.cpp - src/os/panic.cpp - src/os/syscall.cpp - src/os/tty.cpp - src/os/resources/lat9-08.psf.s - src/cstdlib/assert.cpp src/cstdlib/stdio.cpp src/cstdlib/stdlib.cpp src/cstdlib/string.cpp ''') -env.Resource(env.File('src/os/resources/lat9-08.psf').abspath, 'LAT9_08') env.Append(KERNEL_SOURCES = [env.File(f) for f in any_target_sources]) -env.Append(KERNEL_ISR_SOURCES = [env.File(f) for f in isr_sources]) + +env = SConscript('kernel/SConscript', exports = 'env') Return('env') \ No newline at end of file diff --git a/targets/_any/include/os/interrupt.hpp b/targets/_any/include/os/interrupt.hpp deleted file mode 100644 index 447d8e9..0000000 --- a/targets/_any/include/os/interrupt.hpp +++ /dev/null @@ -1,47 +0,0 @@ - -#pragma once - -#if !defined(BAD_APPLE_OS_INTERRUPT_HPP_INCLUDED) -#define BAD_APPLE_OS_INTERRUPT_HPP_INCLUDED - -#include - -namespace baos -{ -#if defined(__x86_64__) -struct InterruptFrame -{ - std::uint64_t ip; - std::uint64_t cs; - std::uint64_t flags; - std::uint64_t sp; - std::uint64_t ss; -}; -using interrupt_error_code_t = std::uint64_t; -#endif - -using interrupt_handler_t = __attribute__((interrupt)) void(*)(baos::InterruptFrame*); -using interrupt_handler_with_error_code_t = __attribute__((interrupt)) void(*)(baos::InterruptFrame*, interrupt_error_code_t); - -__attribute__((interrupt)) -void isrDivisionError(InterruptFrame* interruptFrame) noexcept; - -__attribute__((interrupt)) void isrOverflow(InterruptFrame* interruptFrame) noexcept; -__attribute__((interrupt)) void isrBoundRangeExceeded(InterruptFrame* interruptFrame) noexcept; -__attribute__((interrupt)) void isrInvalidOpCode(InterruptFrame* interruptFrame) noexcept; -__attribute__((interrupt)) void isrDeviceNotAvailable(InterruptFrame* interruptFrame) noexcept; -__attribute__((interrupt)) void isrDoubleFault(InterruptFrame* interruptFrame) noexcept; -__attribute__((interrupt)) void isrInvalidTSS(InterruptFrame* interruptFrame, interrupt_error_code_t errorCode) noexcept; -__attribute__((interrupt)) void isrSegmentNotPresent(InterruptFrame* interruptFrame, interrupt_error_code_t errorCode) noexcept; -__attribute__((interrupt)) void isrStackSegmentFault(InterruptFrame* interruptFrame, interrupt_error_code_t errorCode) noexcept; -__attribute__((interrupt)) void isrGeneralProtectionFault(InterruptFrame* interruptFrame, interrupt_error_code_t errorCode) noexcept; -__attribute__((interrupt)) void isrPageFault(InterruptFrame* interruptFrame, interrupt_error_code_t errorCode) noexcept; -__attribute__((interrupt)) void isrX87FPException(InterruptFrame* interruptFrame) noexcept; -__attribute__((interrupt)) void isrAlignmentCheck(InterruptFrame* interruptFrame, interrupt_error_code_t errorCode) noexcept; -__attribute__((interrupt)) void isrMachineCheck(InterruptFrame* interruptFrame) noexcept; -__attribute__((interrupt)) void isrSimdFpException(InterruptFrame* interruptFrame) noexcept; -__attribute__((interrupt)) void isrVirtualizationException(InterruptFrame* interruptFrame) noexcept; -__attribute__((interrupt)) void isrControlProtectionException(InterruptFrame* interruptFrame, interrupt_error_code_t errorCode) noexcept; -} - -#endif // !defined(BAD_APPLE_OS_INTERRUPT_HPP_INCLUDED) diff --git a/targets/_any/kernel/SConscript b/targets/_any/kernel/SConscript new file mode 100644 index 0000000..a4801d2 --- /dev/null +++ b/targets/_any/kernel/SConscript @@ -0,0 +1,57 @@ +Import('env') + +def _resource(env, res, symbol): + def _generate_s(target, source, env): + with open(target[0].abspath, 'w') as f: + f.write(f''' + .section .rodata + .global {symbol} + .type {symbol} @object + + .section .rodata + .global {symbol}_SIZE + .type {symbol}_SIZE @object +{symbol}: + .incbin "{res}" +{symbol}_END: +{symbol}_SIZE: + .int {symbol}_END - {symbol} +''') + with open(target[1].abspath, 'w') as f: + f.write(f''' +#pragma once + +#include + +extern "C" +{{ +extern const uint8_t {symbol}[]; +extern const unsigned {symbol}_SIZE; +}} + +''') + env.Command([f'{res}.s', f'{res}.hpp'.replace('src/', 'include/')], res, action = _generate_s) +env.AddMethod(_resource, 'Resource') + +isr_sources = Split(''' + src/drivers/pic.cpp + src/drivers/ps2.cpp + src/interrupt.cpp +''') +any_target_sources = Split(''' + src/drivers/pci.cpp + src/drivers/usb.cpp + + src/draw.cpp + src/memory.cpp + src/panic.cpp + src/syscall.cpp + src/tty.cpp + src/resources/lat9-08.psf.s +''') +env.Resource(env.File('src/resources/lat9-08.psf').abspath, 'LAT9_08') + +env.Append(KERNEL_SOURCES = [env.File(f) for f in any_target_sources]) +env.Append(KERNEL_ISR_SOURCES = [env.File(f) for f in isr_sources]) + +Return('env') \ No newline at end of file diff --git a/targets/_any/include/os/cpu.hpp b/targets/_any/kernel/include/os/cpu.hpp similarity index 100% rename from targets/_any/include/os/cpu.hpp rename to targets/_any/kernel/include/os/cpu.hpp diff --git a/targets/_any/include/os/draw.hpp b/targets/_any/kernel/include/os/draw.hpp similarity index 100% rename from targets/_any/include/os/draw.hpp rename to targets/_any/kernel/include/os/draw.hpp diff --git a/targets/_any/kernel/include/os/interrupt.hpp b/targets/_any/kernel/include/os/interrupt.hpp new file mode 100644 index 0000000..0f47153 --- /dev/null +++ b/targets/_any/kernel/include/os/interrupt.hpp @@ -0,0 +1,149 @@ + +#pragma once + +#if !defined(BAD_APPLE_OS_INTERRUPT_HPP_INCLUDED) +#define BAD_APPLE_OS_INTERRUPT_HPP_INCLUDED + +#include +#include +#include + +namespace baos +{ +#if defined(__x86_64__) +inline constexpr std::uint8_t INTERRUPT_DIVISION_ERROR = 0x00; +inline constexpr std::uint8_t INTERRUPT_OVERFLOW = 0x04; +inline constexpr std::uint8_t INTERRUPT_BOUND_RANGE_EXCEEDED = 0x05; +inline constexpr std::uint8_t INTERRUPT_INVALID_OPCODE = 0x06; +inline constexpr std::uint8_t INTERRUPT_DEVICE_NOT_AVAILABLE = 0x07; +inline constexpr std::uint8_t INTERRUPT_DOUBLE_FAULT = 0x08; +inline constexpr std::uint8_t INTERRUPT_INVALID_TSS = 0x0A; +inline constexpr std::uint8_t INTERRUPT_SEGMENT_NOT_PRESENT = 0x0B; +inline constexpr std::uint8_t INTERRUPT_STACK_SEGMENT_FAULT = 0x0C; +inline constexpr std::uint8_t INTERRUPT_GENERAL_PROTECTION_FAULT = 0x0D; +inline constexpr std::uint8_t INTERRUPT_PAGE_FAULT = 0x0E; +inline constexpr std::uint8_t INTERRUPT_X87_FP_EXCEPTION = 0x10; +inline constexpr std::uint8_t INTERRUPT_ALIGNMENT_CHECK = 0x11; +inline constexpr std::uint8_t INTERRUPT_MACHINE_CHECK = 0x12; +inline constexpr std::uint8_t INTERRUPT_SIMD_FP_EXCEPTION = 0x13; +inline constexpr std::uint8_t INTERRUPT_VIRTUALIZATION_EXCEPTION = 0x14; +inline constexpr std::uint8_t INTERRUPT_CONTROL_PROTECTION_EXCEPTION = 0x15; + +struct InterruptFrame +{ + std::uint64_t ip; + std::uint64_t cs; + std::uint64_t flags; + std::uint64_t sp; + std::uint64_t ss; +}; +using interrupt_error_code_t = std::uint64_t; + +enum class InterruptGateType +{ + NONE = 0, + INTERRUPT_GATE = 0xE, + TRAP_GATE = 0xF +}; + +enum class InterruptSelectorTable +{ + GDT = 0, + LDT = 1 +}; + +struct InterruptDescriptor +{ + /* 0 */ unsigned offsetLow : 16 = 0; + /* 16 */ unsigned selectorPrivilegeLevel : 2 = 0; + /* 18 */ InterruptSelectorTable selectorTable : 1 = InterruptSelectorTable::GDT; + /* 19 */ unsigned selectorIndex : 13 = 0; + /* 32 */ unsigned interruptStackTable : 3 = 0; + /* 35 */ unsigned reserved0_ : 5 = 0; + /* 40 */ InterruptGateType gateType : 4 = InterruptGateType::NONE; + /* 44 */ unsigned reserved1_ : 1 = 0; + /* 45 */ unsigned privilegeLevel : 2 = 0; + /* 47 */ bool present : 1 = 0; + /* 48 */ unsigned long offsetHigh : 48 = 0; + /* 96 */ unsigned reserved2_ : 32 = 0; +} __attribute__((packed)); + +class InterruptDescriptorTable +{ +private: + alignas(16) std::array mDescriptors; +public: + inline void install() const noexcept; + + template + void setupInterrupt(std::uint8_t index, THandler handler) noexcept + { + const std::uint64_t offset = std::bit_cast(handler); + mDescriptors[index] = InterruptDescriptor{ + .offsetLow = static_cast(offset & 0xFFFF), + .selectorPrivilegeLevel = 0, + .selectorIndex = 1, // kernel code + .interruptStackTable = 0, + .gateType = InterruptGateType::INTERRUPT_GATE, + .privilegeLevel = 0, + .present = true, + .offsetHigh = (offset >> 16) + }; + } + + inline void setupErrorInterrupts() noexcept; +}; +#endif + +using interrupt_handler_t = __attribute__((interrupt)) void(*)(baos::InterruptFrame*); +using interrupt_handler_with_error_code_t = __attribute__((interrupt)) void(*)(baos::InterruptFrame*, interrupt_error_code_t); + +__attribute__((interrupt)) +void isrDivisionError(InterruptFrame* interruptFrame) noexcept; + +__attribute__((interrupt)) void isrOverflow(InterruptFrame* interruptFrame) noexcept; +__attribute__((interrupt)) void isrBoundRangeExceeded(InterruptFrame* interruptFrame) noexcept; +__attribute__((interrupt)) void isrInvalidOpCode(InterruptFrame* interruptFrame) noexcept; +__attribute__((interrupt)) void isrDeviceNotAvailable(InterruptFrame* interruptFrame) noexcept; +__attribute__((interrupt)) void isrDoubleFault(InterruptFrame* interruptFrame) noexcept; +__attribute__((interrupt)) void isrInvalidTSS(InterruptFrame* interruptFrame, interrupt_error_code_t errorCode) noexcept; +__attribute__((interrupt)) void isrSegmentNotPresent(InterruptFrame* interruptFrame, interrupt_error_code_t errorCode) noexcept; +__attribute__((interrupt)) void isrStackSegmentFault(InterruptFrame* interruptFrame, interrupt_error_code_t errorCode) noexcept; +__attribute__((interrupt)) void isrGeneralProtectionFault(InterruptFrame* interruptFrame, interrupt_error_code_t errorCode) noexcept; +__attribute__((interrupt)) void isrPageFault(InterruptFrame* interruptFrame, interrupt_error_code_t errorCode) noexcept; +__attribute__((interrupt)) void isrX87FPException(InterruptFrame* interruptFrame) noexcept; +__attribute__((interrupt)) void isrAlignmentCheck(InterruptFrame* interruptFrame, interrupt_error_code_t errorCode) noexcept; +__attribute__((interrupt)) void isrMachineCheck(InterruptFrame* interruptFrame) noexcept; +__attribute__((interrupt)) void isrSimdFpException(InterruptFrame* interruptFrame) noexcept; +__attribute__((interrupt)) void isrVirtualizationException(InterruptFrame* interruptFrame) noexcept; +__attribute__((interrupt)) void isrControlProtectionException(InterruptFrame* interruptFrame, interrupt_error_code_t errorCode) noexcept; + +extern "C" void __setIDT(uint16_t limit, const void* base); +void InterruptDescriptorTable::install() const noexcept +{ + __setIDT(sizeof(mDescriptors), &mDescriptors); +} + +void InterruptDescriptorTable::setupErrorInterrupts() noexcept +{ + setupInterrupt(INTERRUPT_DIVISION_ERROR, &isrDivisionError); + setupInterrupt(INTERRUPT_OVERFLOW, &isrOverflow); + setupInterrupt(INTERRUPT_BOUND_RANGE_EXCEEDED, &isrBoundRangeExceeded); + setupInterrupt(INTERRUPT_INVALID_OPCODE, &isrInvalidOpCode); + setupInterrupt(INTERRUPT_DEVICE_NOT_AVAILABLE, &isrDeviceNotAvailable); + setupInterrupt(INTERRUPT_DOUBLE_FAULT, &isrDoubleFault); + setupInterrupt(INTERRUPT_INVALID_TSS, &isrInvalidTSS); + setupInterrupt(INTERRUPT_SEGMENT_NOT_PRESENT, &isrSegmentNotPresent); + setupInterrupt(INTERRUPT_STACK_SEGMENT_FAULT, &isrStackSegmentFault); + setupInterrupt(INTERRUPT_GENERAL_PROTECTION_FAULT, &isrGeneralProtectionFault); + setupInterrupt(INTERRUPT_PAGE_FAULT, &isrPageFault); + setupInterrupt(INTERRUPT_X87_FP_EXCEPTION, &isrX87FPException); + setupInterrupt(INTERRUPT_ALIGNMENT_CHECK, &isrAlignmentCheck); + setupInterrupt(INTERRUPT_MACHINE_CHECK, &isrMachineCheck); + setupInterrupt(INTERRUPT_SIMD_FP_EXCEPTION, &isrSimdFpException); + setupInterrupt(INTERRUPT_VIRTUALIZATION_EXCEPTION, &isrVirtualizationException); + setupInterrupt(INTERRUPT_CONTROL_PROTECTION_EXCEPTION, &isrControlProtectionException); +} +} + +#endif // !defined(BAD_APPLE_OS_INTERRUPT_HPP_INCLUDED) diff --git a/targets/_any/include/os/memory.hpp b/targets/_any/kernel/include/os/memory.hpp similarity index 100% rename from targets/_any/include/os/memory.hpp rename to targets/_any/kernel/include/os/memory.hpp diff --git a/targets/_any/include/os/panic.hpp b/targets/_any/kernel/include/os/panic.hpp similarity index 100% rename from targets/_any/include/os/panic.hpp rename to targets/_any/kernel/include/os/panic.hpp diff --git a/targets/_any/include/os/port.hpp b/targets/_any/kernel/include/os/port.hpp similarity index 100% rename from targets/_any/include/os/port.hpp rename to targets/_any/kernel/include/os/port.hpp diff --git a/targets/_any/include/os/segments.hpp b/targets/_any/kernel/include/os/segments.hpp similarity index 100% rename from targets/_any/include/os/segments.hpp rename to targets/_any/kernel/include/os/segments.hpp diff --git a/targets/_any/include/os/serial.hpp b/targets/_any/kernel/include/os/serial.hpp similarity index 100% rename from targets/_any/include/os/serial.hpp rename to targets/_any/kernel/include/os/serial.hpp diff --git a/targets/_any/include/os/syscall.hpp b/targets/_any/kernel/include/os/syscall.hpp similarity index 100% rename from targets/_any/include/os/syscall.hpp rename to targets/_any/kernel/include/os/syscall.hpp diff --git a/targets/_any/include/os/tools/printf_helper.hpp b/targets/_any/kernel/include/os/tools/printf_helper.hpp similarity index 100% rename from targets/_any/include/os/tools/printf_helper.hpp rename to targets/_any/kernel/include/os/tools/printf_helper.hpp diff --git a/targets/_any/include/os/tools/ringbuffer.hpp b/targets/_any/kernel/include/os/tools/ringbuffer.hpp similarity index 100% rename from targets/_any/include/os/tools/ringbuffer.hpp rename to targets/_any/kernel/include/os/tools/ringbuffer.hpp diff --git a/targets/_any/include/os/tty.hpp b/targets/_any/kernel/include/os/tty.hpp similarity index 100% rename from targets/_any/include/os/tty.hpp rename to targets/_any/kernel/include/os/tty.hpp diff --git a/targets/_any/include/os/resources/.gitignore b/targets/_any/kernel/include/resources/.gitignore similarity index 100% rename from targets/_any/include/os/resources/.gitignore rename to targets/_any/kernel/include/resources/.gitignore diff --git a/targets/_any/src/os/draw.cpp b/targets/_any/kernel/src/draw.cpp similarity index 100% rename from targets/_any/src/os/draw.cpp rename to targets/_any/kernel/src/draw.cpp diff --git a/targets/_any/src/drivers/pci.cpp b/targets/_any/kernel/src/drivers/pci.cpp similarity index 100% rename from targets/_any/src/drivers/pci.cpp rename to targets/_any/kernel/src/drivers/pci.cpp diff --git a/targets/_any/src/drivers/pic.cpp b/targets/_any/kernel/src/drivers/pic.cpp similarity index 100% rename from targets/_any/src/drivers/pic.cpp rename to targets/_any/kernel/src/drivers/pic.cpp diff --git a/targets/_any/src/drivers/ps2.cpp b/targets/_any/kernel/src/drivers/ps2.cpp similarity index 100% rename from targets/_any/src/drivers/ps2.cpp rename to targets/_any/kernel/src/drivers/ps2.cpp diff --git a/targets/_any/src/drivers/usb.cpp b/targets/_any/kernel/src/drivers/usb.cpp similarity index 100% rename from targets/_any/src/drivers/usb.cpp rename to targets/_any/kernel/src/drivers/usb.cpp diff --git a/targets/_any/src/os/interrupt.cpp b/targets/_any/kernel/src/interrupt.cpp similarity index 100% rename from targets/_any/src/os/interrupt.cpp rename to targets/_any/kernel/src/interrupt.cpp diff --git a/targets/_any/src/os/memory.cpp b/targets/_any/kernel/src/memory.cpp similarity index 100% rename from targets/_any/src/os/memory.cpp rename to targets/_any/kernel/src/memory.cpp diff --git a/targets/_any/src/os/panic.cpp b/targets/_any/kernel/src/panic.cpp similarity index 100% rename from targets/_any/src/os/panic.cpp rename to targets/_any/kernel/src/panic.cpp diff --git a/targets/_any/src/os/resources/.gitignore b/targets/_any/kernel/src/resources/.gitignore similarity index 100% rename from targets/_any/src/os/resources/.gitignore rename to targets/_any/kernel/src/resources/.gitignore diff --git a/targets/_any/src/os/resources/lat9-08.psf b/targets/_any/kernel/src/resources/lat9-08.psf similarity index 100% rename from targets/_any/src/os/resources/lat9-08.psf rename to targets/_any/kernel/src/resources/lat9-08.psf diff --git a/targets/_any/src/os/syscall.cpp b/targets/_any/kernel/src/syscall.cpp similarity index 100% rename from targets/_any/src/os/syscall.cpp rename to targets/_any/kernel/src/syscall.cpp diff --git a/targets/_any/src/os/tty.cpp b/targets/_any/kernel/src/tty.cpp similarity index 99% rename from targets/_any/src/os/tty.cpp rename to targets/_any/kernel/src/tty.cpp index 4e73e69..670bc70 100644 --- a/targets/_any/src/os/tty.cpp +++ b/targets/_any/kernel/src/tty.cpp @@ -6,7 +6,7 @@ #include "drivers/ps2.hpp" #include "libs/psf.hpp" #include "os/draw.hpp" -#include "os/resources/lat9-08.psf.hpp" +#include "resources/lat9-08.psf.hpp" namespace tty { diff --git a/targets/_any/src/cstdlib/stdio.cpp b/targets/_any/src/cstdlib/stdio.cpp index 56351ad..e976154 100644 --- a/targets/_any/src/cstdlib/stdio.cpp +++ b/targets/_any/src/cstdlib/stdio.cpp @@ -3,11 +3,16 @@ #include #include -#include "os/syscall.hpp" #include "os/tty.hpp" #include "os/tools/printf_helper.hpp" #include "os/tools/ringbuffer.hpp" +#if defined(__baos_kernel_source__) +#include "os/serial.hpp" +#else +#include "os/syscall.hpp" +#endif + struct __file { protected: @@ -111,9 +116,10 @@ extern "C" { FILE* __stdin = &gStdin; +// TODO: line-buffering int putchar(int chr) noexcept { -#if 0 +#if defined(__baos_kernel_source__) tty::putChar(static_cast(chr)); if (chr == '\n') { @@ -125,17 +131,16 @@ int putchar(int chr) noexcept serialWrite(PORT_COM1, static_cast(chr)); } return 0; -#endif +#else char asChar = static_cast(chr); baos::doSyscall(baos::Syscall::FILE_WRITE, 0, &asChar, 1); return 0; +#endif } int puts(const char* str) noexcept { - baos::doSyscall(baos::Syscall::FILE_WRITE, 0, str, std::strlen(str)); - return 0; -#if 0 +#if defined(__baos_kernel_source__) while (*str) { putchar(*str); @@ -143,6 +148,9 @@ int puts(const char* str) noexcept } putchar('\n'); return 0; +#else + baos::doSyscall(baos::Syscall::FILE_WRITE, 0, str, std::strlen(str)); + return 0; #endif } diff --git a/targets/x86_64/SConscript b/targets/x86_64/SConscript index f3b02c8..3fb9c42 100644 --- a/targets/x86_64/SConscript +++ b/targets/x86_64/SConscript @@ -8,9 +8,10 @@ kernel_env['CXX'] = 'x86_64-elf-g++' kernel_env['LD'] = 'x86_64-elf-g++' kernel_env.Append(CFLAGS = ['-ffreestanding']) +kernel_env.Append(CPPDEFINES = ['__baos_kernel_source__=1']) kernel_env.Append(CXXFLAGS = ['-ffreestanding', '-fno-exceptions', '-fno-rtti', '-std=c++20']) kernel_env.Append(LINKFLAGS = ['-T', kernel_env.File('linker.ld').abspath, '-ffreestanding', '-nostdlib', '-mcmodel=large', '-mno-red-zone', '-mno-mmx', '-mno-sse', '-mno-sse2']) -kernel_env.Append(CPPPATH = ['#targets/_any/include', '#bastl/include', 'include', '/usr/include/efi']) +kernel_env.Append(CPPPATH = ['#targets/_any/include', '#bastl/include', 'include', '/usr/include/efi', '#targets/_any/kernel/include']) def get_crt_object(name: str) -> str: import subprocess diff --git a/targets/x86_64/src/kernel/boot.s b/targets/x86_64/src/kernel/boot.s index 8d80ad9..e65c1c9 100644 --- a/targets/x86_64/src/kernel/boot.s +++ b/targets/x86_64/src/kernel/boot.s @@ -61,7 +61,7 @@ __setGDT: .global __setIDT .type __setIDT @function -// void __setIDT(uint16_t limit [%di], void* base [%rsi]) +// void __setIDT(uint16_t limit [%di], const void* base [%rsi]) __setIDT: movw %di, __idt_storage movq %rsi, (__idt_storage + 2) diff --git a/targets/x86_64/src/kernel/startup.cpp b/targets/x86_64/src/kernel/startup.cpp index 6f2e5f7..7b6e3ae 100644 --- a/targets/x86_64/src/kernel/startup.cpp +++ b/targets/x86_64/src/kernel/startup.cpp @@ -32,23 +32,6 @@ constexpr std::uint8_t irqToInterrupt(std::uint8_t irq) noexcept } return SLAVE_PIC_OFFSET + irq; } -inline constexpr std::uint8_t INTERRUPT_DIVISION_ERROR = 0x00; -inline constexpr std::uint8_t INTERRUPT_OVERFLOW = 0x04; -inline constexpr std::uint8_t INTERRUPT_BOUND_RANGE_EXCEEDED = 0x05; -inline constexpr std::uint8_t INTERRUPT_INVALID_OPCODE = 0x06; -inline constexpr std::uint8_t INTERRUPT_DEVICE_NOT_AVAILABLE = 0x07; -inline constexpr std::uint8_t INTERRUPT_DOUBLE_FAULT = 0x08; -inline constexpr std::uint8_t INTERRUPT_INVALID_TSS = 0x0A; -inline constexpr std::uint8_t INTERRUPT_SEGMENT_NOT_PRESENT = 0x0B; -inline constexpr std::uint8_t INTERRUPT_STACK_SEGMENT_FAULT = 0x0C; -inline constexpr std::uint8_t INTERRUPT_GENERAL_PROTECTION_FAULT = 0x0D; -inline constexpr std::uint8_t INTERRUPT_PAGE_FAULT = 0x0E; -inline constexpr std::uint8_t INTERRUPT_X87_FP_EXCEPTION = 0x10; -inline constexpr std::uint8_t INTERRUPT_ALIGNMENT_CHECK = 0x11; -inline constexpr std::uint8_t INTERRUPT_MACHINE_CHECK = 0x12; -inline constexpr std::uint8_t INTERRUPT_SIMD_FP_EXCEPTION = 0x13; -inline constexpr std::uint8_t INTERRUPT_VIRTUALIZATION_EXCEPTION = 0x14; -inline constexpr std::uint8_t INTERRUPT_CONTROL_PROTECTION_EXCEPTION = 0x15; inline constexpr std::uint8_t INTERRUPT_KEYBOARD = irqToInterrupt(1); TaskStateSegment tss alignas(16); @@ -63,8 +46,7 @@ constinit std::array GDT alignas(16) = { SEGMENT_NULL // TSS higher }; -constinit std::array IDT alignas(16); - +constinit baos::InterruptDescriptorTable gInterruptDescriptorTable; inline baos::MemoryType mapEfiMemoryType(UINT32 type) noexcept { @@ -145,27 +127,10 @@ void initGlobals() } extern "C" void __setGDT(uint16_t limit, void* base); -extern "C" void __setIDT(uint16_t limit, void* base); extern "C" void __reloadSegments(uint64_t code, uint64_t data); extern "C" void __flushTSS(uint16_t segment); extern "C" void __enterUsermode(uint16_t codeSegment, uint16_t dataSegment, void* rsp, void (*function)(), void* stackPtr); -template -void setupInterrupt(std::uint8_t index, THandler handler) noexcept -{ - const std::uint64_t offset = std::bit_cast(handler); - IDT[index] = InterruptDescriptor{ - .offsetLow = static_cast(offset & 0xFFFF), - .selectorPrivilegeLevel = 0, - .selectorIndex = 1, // kernel code - .interruptStackTable = 0, - .gateType = InterruptGateType::INTERRUPT_GATE, - .privilegeLevel = 0, - .present = true, - .offsetHigh = (offset >> 16) - }; -} - void initializePCIDevice(const baos::pci::Header& header) noexcept { using namespace baos; @@ -192,28 +157,12 @@ void kernel_main() { using namespace baos; - setupInterrupt(INTERRUPT_DIVISION_ERROR, &baos::isrDivisionError); - setupInterrupt(INTERRUPT_OVERFLOW, &baos::isrOverflow); - setupInterrupt(INTERRUPT_BOUND_RANGE_EXCEEDED, &baos::isrBoundRangeExceeded); - setupInterrupt(INTERRUPT_INVALID_OPCODE, &baos::isrInvalidOpCode); - setupInterrupt(INTERRUPT_DEVICE_NOT_AVAILABLE, &baos::isrDeviceNotAvailable); - setupInterrupt(INTERRUPT_DOUBLE_FAULT, &baos::isrDoubleFault); - setupInterrupt(INTERRUPT_INVALID_TSS, &baos::isrInvalidTSS); - setupInterrupt(INTERRUPT_SEGMENT_NOT_PRESENT, &baos::isrSegmentNotPresent); - setupInterrupt(INTERRUPT_STACK_SEGMENT_FAULT, &baos::isrStackSegmentFault); - setupInterrupt(INTERRUPT_GENERAL_PROTECTION_FAULT, &baos::isrGeneralProtectionFault); - setupInterrupt(INTERRUPT_PAGE_FAULT, &baos::isrPageFault); - setupInterrupt(INTERRUPT_X87_FP_EXCEPTION, &baos::isrX87FPException); - setupInterrupt(INTERRUPT_ALIGNMENT_CHECK, &baos::isrAlignmentCheck); - setupInterrupt(INTERRUPT_MACHINE_CHECK, &baos::isrMachineCheck); - setupInterrupt(INTERRUPT_SIMD_FP_EXCEPTION, &baos::isrSimdFpException); - setupInterrupt(INTERRUPT_VIRTUALIZATION_EXCEPTION, &baos::isrVirtualizationException); - setupInterrupt(INTERRUPT_CONTROL_PROTECTION_EXCEPTION, &baos::isrControlProtectionException); - setupInterrupt(INTERRUPT_KEYBOARD, &ps2::isrKeyboard); + gInterruptDescriptorTable.setupErrorInterrupts(); + gInterruptDescriptorTable.setupInterrupt(INTERRUPT_KEYBOARD, &ps2::isrKeyboard); makeTSSSegment(&tss, &GDT[5]); __setGDT(sizeof(GDT), &GDT); - __setIDT(sizeof(IDT), &IDT); + gInterruptDescriptorTable.install(); __reloadSegments(SEGIDX_KERNEL_CODE, SEGIDX_KERNEL_DATA); __flushTSS(SEGIDX_TSS); diff --git a/targets/x86_64/src/kernel/x86_64.hpp b/targets/x86_64/src/kernel/x86_64.hpp index 6ca274e..40676fa 100644 --- a/targets/x86_64/src/kernel/x86_64.hpp +++ b/targets/x86_64/src/kernel/x86_64.hpp @@ -171,35 +171,6 @@ inline constexpr const SegmentDescriptor SEGMENT_USER_DATA = { // --- Interrupts --- // -enum class InterruptGateType -{ - NONE = 0, - INTERRUPT_GATE = 0xE, - TRAP_GATE = 0xF -}; - -enum class InterruptSelectorTable -{ - GDT = 0, - LDT = 1 -}; - -struct InterruptDescriptor -{ - /* 0 */ unsigned offsetLow : 16 = 0; - /* 16 */ unsigned selectorPrivilegeLevel : 2 = 0; - /* 18 */ InterruptSelectorTable selectorTable : 1 = InterruptSelectorTable::GDT; - /* 19 */ unsigned selectorIndex : 13 = 0; - /* 32 */ unsigned interruptStackTable : 3 = 0; - /* 35 */ unsigned reserved0_ : 5 = 0; - /* 40 */ InterruptGateType gateType : 4 = InterruptGateType::NONE; - /* 44 */ unsigned reserved1_ : 1 = 0; - /* 45 */ unsigned privilegeLevel : 2 = 0; - /* 47 */ bool present : 1 = 0; - /* 48 */ unsigned long offsetHigh : 48 = 0; - /* 96 */ unsigned reserved2_ : 32 = 0; -} __attribute__((packed)); - struct TaskStateSegment { /* 0 */ std::uint32_t reserved0 = 0;