Some restructuring.
This commit is contained in:
parent
3fff3bd8fc
commit
54a5ee720f
@ -1,66 +1,18 @@
|
|||||||
Import('env')
|
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 <stdint.h>
|
|
||||||
|
|
||||||
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('''
|
any_target_sources = Split('''
|
||||||
src/app/main.cpp
|
src/app/main.cpp
|
||||||
|
|
||||||
src/drivers/pci.cpp
|
|
||||||
src/drivers/usb.cpp
|
|
||||||
|
|
||||||
src/libs/psf.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/assert.cpp
|
||||||
src/cstdlib/stdio.cpp
|
src/cstdlib/stdio.cpp
|
||||||
src/cstdlib/stdlib.cpp
|
src/cstdlib/stdlib.cpp
|
||||||
src/cstdlib/string.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_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')
|
Return('env')
|
@ -1,47 +0,0 @@
|
|||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#if !defined(BAD_APPLE_OS_INTERRUPT_HPP_INCLUDED)
|
|
||||||
#define BAD_APPLE_OS_INTERRUPT_HPP_INCLUDED
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
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)
|
|
57
targets/_any/kernel/SConscript
Normal file
57
targets/_any/kernel/SConscript
Normal file
@ -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 <stdint.h>
|
||||||
|
|
||||||
|
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')
|
149
targets/_any/kernel/include/os/interrupt.hpp
Normal file
149
targets/_any/kernel/include/os/interrupt.hpp
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if !defined(BAD_APPLE_OS_INTERRUPT_HPP_INCLUDED)
|
||||||
|
#define BAD_APPLE_OS_INTERRUPT_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <bit>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
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<InterruptDescriptor, 256> mDescriptors;
|
||||||
|
public:
|
||||||
|
inline void install() const noexcept;
|
||||||
|
|
||||||
|
template<typename THandler>
|
||||||
|
void setupInterrupt(std::uint8_t index, THandler handler) noexcept
|
||||||
|
{
|
||||||
|
const std::uint64_t offset = std::bit_cast<std::uint64_t>(handler);
|
||||||
|
mDescriptors[index] = InterruptDescriptor{
|
||||||
|
.offsetLow = static_cast<unsigned>(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)
|
@ -6,7 +6,7 @@
|
|||||||
#include "drivers/ps2.hpp"
|
#include "drivers/ps2.hpp"
|
||||||
#include "libs/psf.hpp"
|
#include "libs/psf.hpp"
|
||||||
#include "os/draw.hpp"
|
#include "os/draw.hpp"
|
||||||
#include "os/resources/lat9-08.psf.hpp"
|
#include "resources/lat9-08.psf.hpp"
|
||||||
|
|
||||||
namespace tty
|
namespace tty
|
||||||
{
|
{
|
@ -3,11 +3,16 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include "os/syscall.hpp"
|
|
||||||
#include "os/tty.hpp"
|
#include "os/tty.hpp"
|
||||||
#include "os/tools/printf_helper.hpp"
|
#include "os/tools/printf_helper.hpp"
|
||||||
#include "os/tools/ringbuffer.hpp"
|
#include "os/tools/ringbuffer.hpp"
|
||||||
|
|
||||||
|
#if defined(__baos_kernel_source__)
|
||||||
|
#include "os/serial.hpp"
|
||||||
|
#else
|
||||||
|
#include "os/syscall.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
struct __file
|
struct __file
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
@ -111,9 +116,10 @@ extern "C"
|
|||||||
{
|
{
|
||||||
FILE* __stdin = &gStdin;
|
FILE* __stdin = &gStdin;
|
||||||
|
|
||||||
|
// TODO: line-buffering
|
||||||
int putchar(int chr) noexcept
|
int putchar(int chr) noexcept
|
||||||
{
|
{
|
||||||
#if 0
|
#if defined(__baos_kernel_source__)
|
||||||
tty::putChar(static_cast<char>(chr));
|
tty::putChar(static_cast<char>(chr));
|
||||||
if (chr == '\n')
|
if (chr == '\n')
|
||||||
{
|
{
|
||||||
@ -125,17 +131,16 @@ int putchar(int chr) noexcept
|
|||||||
serialWrite(PORT_COM1, static_cast<std::uint8_t>(chr));
|
serialWrite(PORT_COM1, static_cast<std::uint8_t>(chr));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#else
|
||||||
char asChar = static_cast<char>(chr);
|
char asChar = static_cast<char>(chr);
|
||||||
baos::doSyscall(baos::Syscall::FILE_WRITE, 0, &asChar, 1);
|
baos::doSyscall(baos::Syscall::FILE_WRITE, 0, &asChar, 1);
|
||||||
return 0;
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int puts(const char* str) noexcept
|
int puts(const char* str) noexcept
|
||||||
{
|
{
|
||||||
baos::doSyscall(baos::Syscall::FILE_WRITE, 0, str, std::strlen(str));
|
#if defined(__baos_kernel_source__)
|
||||||
return 0;
|
|
||||||
#if 0
|
|
||||||
while (*str)
|
while (*str)
|
||||||
{
|
{
|
||||||
putchar(*str);
|
putchar(*str);
|
||||||
@ -143,6 +148,9 @@ int puts(const char* str) noexcept
|
|||||||
}
|
}
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
return 0;
|
return 0;
|
||||||
|
#else
|
||||||
|
baos::doSyscall(baos::Syscall::FILE_WRITE, 0, str, std::strlen(str));
|
||||||
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,9 +8,10 @@ kernel_env['CXX'] = 'x86_64-elf-g++'
|
|||||||
kernel_env['LD'] = 'x86_64-elf-g++'
|
kernel_env['LD'] = 'x86_64-elf-g++'
|
||||||
|
|
||||||
kernel_env.Append(CFLAGS = ['-ffreestanding'])
|
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(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(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:
|
def get_crt_object(name: str) -> str:
|
||||||
import subprocess
|
import subprocess
|
||||||
|
@ -61,7 +61,7 @@ __setGDT:
|
|||||||
|
|
||||||
.global __setIDT
|
.global __setIDT
|
||||||
.type __setIDT @function
|
.type __setIDT @function
|
||||||
// void __setIDT(uint16_t limit [%di], void* base [%rsi])
|
// void __setIDT(uint16_t limit [%di], const void* base [%rsi])
|
||||||
__setIDT:
|
__setIDT:
|
||||||
movw %di, __idt_storage
|
movw %di, __idt_storage
|
||||||
movq %rsi, (__idt_storage + 2)
|
movq %rsi, (__idt_storage + 2)
|
||||||
|
@ -32,23 +32,6 @@ constexpr std::uint8_t irqToInterrupt(std::uint8_t irq) noexcept
|
|||||||
}
|
}
|
||||||
return SLAVE_PIC_OFFSET + irq;
|
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);
|
inline constexpr std::uint8_t INTERRUPT_KEYBOARD = irqToInterrupt(1);
|
||||||
|
|
||||||
TaskStateSegment tss alignas(16);
|
TaskStateSegment tss alignas(16);
|
||||||
@ -63,8 +46,7 @@ constinit std::array GDT alignas(16) = {
|
|||||||
SEGMENT_NULL // TSS higher
|
SEGMENT_NULL // TSS higher
|
||||||
};
|
};
|
||||||
|
|
||||||
constinit std::array<InterruptDescriptor, 256> IDT alignas(16);
|
constinit baos::InterruptDescriptorTable gInterruptDescriptorTable;
|
||||||
|
|
||||||
|
|
||||||
inline baos::MemoryType mapEfiMemoryType(UINT32 type) noexcept
|
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 __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 __reloadSegments(uint64_t code, uint64_t data);
|
||||||
extern "C" void __flushTSS(uint16_t segment);
|
extern "C" void __flushTSS(uint16_t segment);
|
||||||
extern "C" void __enterUsermode(uint16_t codeSegment, uint16_t dataSegment, void* rsp, void (*function)(), void* stackPtr);
|
extern "C" void __enterUsermode(uint16_t codeSegment, uint16_t dataSegment, void* rsp, void (*function)(), void* stackPtr);
|
||||||
|
|
||||||
template<typename THandler>
|
|
||||||
void setupInterrupt(std::uint8_t index, THandler handler) noexcept
|
|
||||||
{
|
|
||||||
const std::uint64_t offset = std::bit_cast<std::uint64_t>(handler);
|
|
||||||
IDT[index] = InterruptDescriptor{
|
|
||||||
.offsetLow = static_cast<unsigned>(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
|
void initializePCIDevice(const baos::pci::Header& header) noexcept
|
||||||
{
|
{
|
||||||
using namespace baos;
|
using namespace baos;
|
||||||
@ -192,28 +157,12 @@ void kernel_main()
|
|||||||
{
|
{
|
||||||
using namespace baos;
|
using namespace baos;
|
||||||
|
|
||||||
setupInterrupt(INTERRUPT_DIVISION_ERROR, &baos::isrDivisionError);
|
gInterruptDescriptorTable.setupErrorInterrupts();
|
||||||
setupInterrupt(INTERRUPT_OVERFLOW, &baos::isrOverflow);
|
gInterruptDescriptorTable.setupInterrupt(INTERRUPT_KEYBOARD, &ps2::isrKeyboard);
|
||||||
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);
|
|
||||||
|
|
||||||
makeTSSSegment(&tss, &GDT[5]);
|
makeTSSSegment(&tss, &GDT[5]);
|
||||||
__setGDT(sizeof(GDT), &GDT);
|
__setGDT(sizeof(GDT), &GDT);
|
||||||
__setIDT(sizeof(IDT), &IDT);
|
gInterruptDescriptorTable.install();
|
||||||
__reloadSegments(SEGIDX_KERNEL_CODE, SEGIDX_KERNEL_DATA);
|
__reloadSegments(SEGIDX_KERNEL_CODE, SEGIDX_KERNEL_DATA);
|
||||||
__flushTSS(SEGIDX_TSS);
|
__flushTSS(SEGIDX_TSS);
|
||||||
|
|
||||||
|
@ -171,35 +171,6 @@ inline constexpr const SegmentDescriptor SEGMENT_USER_DATA = {
|
|||||||
|
|
||||||
// --- Interrupts --- //
|
// --- 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
|
struct TaskStateSegment
|
||||||
{
|
{
|
||||||
/* 0 */ std::uint32_t reserved0 = 0;
|
/* 0 */ std::uint32_t reserved0 = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user