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.Command([f'{res}.s', f'{res}.hpp'.replace('src/', 'include/')], res, action = _generate_s)
|
||||||
env.AddMethod(_resource, 'Resource')
|
env.AddMethod(_resource, 'Resource')
|
||||||
|
|
||||||
irs_sources = Split('''
|
isr_sources = Split('''
|
||||||
src/drivers/pic.cpp
|
src/drivers/pic.cpp
|
||||||
src/drivers/ps2.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
|
||||||
@ -55,6 +56,6 @@ any_target_sources = Split('''
|
|||||||
env.Resource(env.File('src/os/resources/lat9-08.psf').abspath, 'LAT9_08')
|
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 irs_sources])
|
env.Append(KERNEL_ISR_SOURCES = [env.File(f) for f in isr_sources])
|
||||||
|
|
||||||
Return('env')
|
Return('env')
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "os/interrupt.hpp"
|
||||||
#include "os/port.hpp"
|
#include "os/port.hpp"
|
||||||
|
|
||||||
inline constexpr std::uint16_t PORT_PIC1 = 0x20;
|
inline constexpr std::uint16_t PORT_PIC1 = 0x20;
|
||||||
@ -25,17 +26,4 @@ void unmaskIRQ(std::uint8_t irq) noexcept;
|
|||||||
return (offset & 7) == 0;
|
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)
|
#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;
|
const size_t byteDist = scrollY * bytesPerRow;
|
||||||
uint8_t* basePtr = reinterpret_cast<uint8_t*>(gDoubleBuffer.getBase());
|
uint8_t* basePtr = reinterpret_cast<uint8_t*>(gDoubleBuffer.getBase());
|
||||||
std::memmove(basePtr, basePtr + byteDist, bytesToMove);
|
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);
|
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.
|
// We are done. Clear interrupts and halt.
|
||||||
cli
|
cli
|
||||||
.kernel_end:
|
|
||||||
|
.global __halt
|
||||||
|
.type __halt @function
|
||||||
|
__halt:
|
||||||
hlt
|
hlt
|
||||||
jmp .kernel_end
|
jmp __halt
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.global __setGDT
|
.global __setGDT
|
||||||
.type __setGDT @function
|
.type __setGDT @function
|
||||||
|
@ -27,6 +27,23 @@ 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);
|
||||||
|
|
||||||
constinit std::array GDT alignas(16) = {
|
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 __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);
|
||||||
|
|
||||||
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);
|
const std::uint64_t offset = std::bit_cast<std::uint64_t>(handler);
|
||||||
IDT[index] = InterruptDescriptor{
|
IDT[index] = InterruptDescriptor{
|
||||||
@ -139,13 +157,28 @@ EfiBootInfo* gBootInfo;
|
|||||||
|
|
||||||
void main();
|
void main();
|
||||||
|
|
||||||
extern void __isr21(InterruptFrame*);
|
|
||||||
|
|
||||||
void kernel_main()
|
void kernel_main()
|
||||||
{
|
{
|
||||||
using namespace baos;
|
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);
|
__setGDT(sizeof(GDT), &GDT);
|
||||||
__setIDT(sizeof(IDT), &IDT);
|
__setIDT(sizeof(IDT), &IDT);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user