Added handlers for some interrupts and fixed terminal scrolling.
This commit is contained in:
parent
c097da920d
commit
9f1f1e80f2
@ -33,9 +33,10 @@ extern const unsigned {symbol}_SIZE;
|
||||
env.Command([f'{res}.s', f'{res}.hpp'.replace('src/', 'include/')], res, action = _generate_s)
|
||||
env.AddMethod(_resource, 'Resource')
|
||||
|
||||
irs_sources = Split('''
|
||||
isr_sources = Split('''
|
||||
src/drivers/pic.cpp
|
||||
src/drivers/ps2.cpp
|
||||
src/os/interrupt.cpp
|
||||
''')
|
||||
any_target_sources = Split('''
|
||||
src/app/main.cpp
|
||||
@ -55,6 +56,6 @@ any_target_sources = Split('''
|
||||
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 irs_sources])
|
||||
env.Append(KERNEL_ISR_SOURCES = [env.File(f) for f in isr_sources])
|
||||
|
||||
Return('env')
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "os/interrupt.hpp"
|
||||
#include "os/port.hpp"
|
||||
|
||||
inline constexpr std::uint16_t PORT_PIC1 = 0x20;
|
||||
@ -25,17 +26,4 @@ void unmaskIRQ(std::uint8_t irq) noexcept;
|
||||
return (offset & 7) == 0;
|
||||
}
|
||||
|
||||
#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;
|
||||
};
|
||||
#endif
|
||||
|
||||
using interrupt_handler_t = __attribute__((interrupt)) void(*)(InterruptFrame*);
|
||||
|
||||
#endif // !defined(BAD_APPLE_OS_KERNEL_PIC_HPP_INCLUDED)
|
||||
|
47
targets/_any/include/os/interrupt.hpp
Normal file
47
targets/_any/include/os/interrupt.hpp
Normal file
@ -0,0 +1,47 @@
|
||||
|
||||
#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)
|
@ -24,7 +24,13 @@ void scrollVertical(int scrollY, const Pixel& fillColor) noexcept
|
||||
const size_t byteDist = scrollY * bytesPerRow;
|
||||
uint8_t* basePtr = reinterpret_cast<uint8_t*>(gDoubleBuffer.getBase());
|
||||
std::memmove(basePtr, basePtr + byteDist, bytesToMove);
|
||||
std::memset(basePtr + byteDist, 0, byteDist);
|
||||
for (unsigned posY = gDoubleBuffer.getHeight() - scrollY; posY < gDoubleBuffer.getHeight(); ++posY)
|
||||
{
|
||||
for (unsigned posX = 0; posX < gDoubleBuffer.getWidth(); ++posX)
|
||||
{
|
||||
gDoubleBuffer.setPixel(posX, posY, fillColor);
|
||||
}
|
||||
}
|
||||
std::memcpy(gFramebuffer.getBase(), gDoubleBuffer.getBase(), gDoubleBuffer.getHeight() * bytesPerRow);
|
||||
}
|
||||
}
|
||||
|
120
targets/_any/src/os/interrupt.cpp
Normal file
120
targets/_any/src/os/interrupt.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
|
||||
#include "os/interrupt.hpp"
|
||||
#include "os/serial.hpp"
|
||||
#include "os/tty.hpp"
|
||||
|
||||
namespace baos
|
||||
{
|
||||
extern "C" [[noreturn]] void __halt();
|
||||
|
||||
__attribute__((no_caller_saved_registers))
|
||||
void handleException(const char* name, InterruptFrame* interruptFrame) noexcept
|
||||
{
|
||||
tty::write(name);
|
||||
serialWriteString(PORT_COM1, name);
|
||||
__halt();
|
||||
}
|
||||
|
||||
__attribute__((interrupt))
|
||||
void isrDivisionError(InterruptFrame* interruptFrame) noexcept
|
||||
{
|
||||
handleException("division error", interruptFrame);
|
||||
}
|
||||
|
||||
__attribute__((interrupt))
|
||||
void isrOverflow(InterruptFrame* interruptFrame) noexcept
|
||||
{
|
||||
handleException("Overflow", interruptFrame);
|
||||
}
|
||||
|
||||
__attribute__((interrupt))
|
||||
void isrBoundRangeExceeded(InterruptFrame* interruptFrame) noexcept
|
||||
{
|
||||
handleException("BoundRangeExceeded", interruptFrame);
|
||||
}
|
||||
|
||||
__attribute__((interrupt))
|
||||
void isrInvalidOpCode(InterruptFrame* interruptFrame) noexcept
|
||||
{
|
||||
handleException("InvalidOpCode", interruptFrame);
|
||||
}
|
||||
|
||||
__attribute__((interrupt))
|
||||
void isrDeviceNotAvailable(InterruptFrame* interruptFrame) noexcept
|
||||
{
|
||||
handleException("DeviceNotAvailable", interruptFrame);
|
||||
}
|
||||
|
||||
__attribute__((interrupt))
|
||||
void isrDoubleFault(InterruptFrame* interruptFrame) noexcept
|
||||
{
|
||||
handleException("DoubleFault", interruptFrame);
|
||||
}
|
||||
|
||||
__attribute__((interrupt))
|
||||
void isrInvalidTSS(InterruptFrame* interruptFrame, interrupt_error_code_t errorCode) noexcept
|
||||
{
|
||||
handleException("InvalidTSS", interruptFrame);
|
||||
}
|
||||
|
||||
__attribute__((interrupt))
|
||||
void isrSegmentNotPresent(InterruptFrame* interruptFrame, interrupt_error_code_t errorCode) noexcept
|
||||
{
|
||||
handleException("SegmentNotPresent", interruptFrame);
|
||||
}
|
||||
|
||||
__attribute__((interrupt))
|
||||
void isrStackSegmentFault(InterruptFrame* interruptFrame, interrupt_error_code_t errorCode) noexcept
|
||||
{
|
||||
handleException("StackSegmentFault", interruptFrame);
|
||||
}
|
||||
|
||||
__attribute__((interrupt))
|
||||
void isrGeneralProtectionFault(InterruptFrame* interruptFrame, interrupt_error_code_t errorCode) noexcept
|
||||
{
|
||||
handleException("GeneralProtectionFault", interruptFrame);
|
||||
}
|
||||
|
||||
__attribute__((interrupt))
|
||||
void isrPageFault(InterruptFrame* interruptFrame, interrupt_error_code_t errorCode) noexcept
|
||||
{
|
||||
handleException("PageFault", interruptFrame);
|
||||
}
|
||||
|
||||
__attribute__((interrupt))
|
||||
void isrX87FPException(InterruptFrame* interruptFrame) noexcept
|
||||
{
|
||||
handleException("X87FPException", interruptFrame);
|
||||
}
|
||||
|
||||
__attribute__((interrupt))
|
||||
void isrAlignmentCheck(InterruptFrame* interruptFrame, interrupt_error_code_t errorCode) noexcept
|
||||
{
|
||||
handleException("AlignmentCheck", interruptFrame);
|
||||
}
|
||||
|
||||
__attribute__((interrupt))
|
||||
void isrMachineCheck(InterruptFrame* interruptFrame) noexcept
|
||||
{
|
||||
handleException("MachineCheck", interruptFrame);
|
||||
}
|
||||
|
||||
__attribute__((interrupt))
|
||||
void isrSimdFpException(InterruptFrame* interruptFrame) noexcept
|
||||
{
|
||||
handleException("SimdFpException", interruptFrame);
|
||||
}
|
||||
|
||||
__attribute__((interrupt))
|
||||
void isrVirtualizationException(InterruptFrame* interruptFrame) noexcept
|
||||
{
|
||||
handleException("VirtualizationException", interruptFrame);
|
||||
}
|
||||
|
||||
__attribute__((interrupt))
|
||||
void isrControlProtectionException(InterruptFrame* interruptFrame, interrupt_error_code_t errorCode) noexcept
|
||||
{
|
||||
handleException("ControlProtectionException", interruptFrame);
|
||||
}
|
||||
|
||||
}
|
@ -41,9 +41,14 @@ _start:
|
||||
|
||||
// We are done. Clear interrupts and halt.
|
||||
cli
|
||||
.kernel_end:
|
||||
|
||||
.global __halt
|
||||
.type __halt @function
|
||||
__halt:
|
||||
hlt
|
||||
jmp .kernel_end
|
||||
jmp __halt
|
||||
|
||||
|
||||
|
||||
.global __setGDT
|
||||
.type __setGDT @function
|
||||
|
@ -27,6 +27,23 @@ 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);
|
||||
|
||||
constinit std::array GDT alignas(16) = {
|
||||
@ -117,7 +134,8 @@ 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);
|
||||
|
||||
void setupInterrupt(std::uint8_t index, interrupt_handler_t handler, std::uint8_t flags) 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);
|
||||
IDT[index] = InterruptDescriptor{
|
||||
@ -139,13 +157,28 @@ EfiBootInfo* gBootInfo;
|
||||
|
||||
void main();
|
||||
|
||||
extern void __isr21(InterruptFrame*);
|
||||
|
||||
void kernel_main()
|
||||
{
|
||||
using namespace baos;
|
||||
|
||||
setupInterrupt(INTERRUPT_KEYBOARD, &ps2::isrKeyboard, 0);
|
||||
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);
|
||||
|
||||
__setGDT(sizeof(GDT), &GDT);
|
||||
__setIDT(sizeof(IDT), &IDT);
|
||||
|
Loading…
x
Reference in New Issue
Block a user