/*! \file All interrupts need to start somewhere. This file contains the entry * points for all interrupts handled by StuBS. * \brief The Interrupt Subsystem * \defgroup interrupts Interrupt Handling */ #pragma once #include "../types.h" /*! \brief Initialize the IDT. * * The interrupt subsystem of StubBS contains all functionality to accept * interrupts from the hardware and process them. * In later exercises the interrupts will enable applications to * execute core functionality (system calls). * The entry point for the interrupt subsystem is the function * 'interrupt_entry_VECTOR' (in `interrupt/handler.asm`). * * \todo(12) Register your own interrupt handlers */ void initInterruptHandlers(); struct InterruptContext; /*! * @brief Helper function for printf-debugging the InterruptContext */ void printContext(const InterruptContext *context); /*! * @brief An interrupt handler for the INVALID_OPCODE trap */ [[gnu::interrupt]] void handle_invalid_opcode(InterruptContext *context); /*! * @brief A double fault occurs when another exception occurs during exception * handling. * * In this case, the OS cannot recover anymore. This can happen e.g. * during page fault handling. */ [[gnu::interrupt]] void handle_double_fault(InterruptContext *context, uint64_t error); /*! * @brief If the task state segment is configured incorrectly, the kernel cannot * switch the privilege levels during interrupts. */ [[gnu::interrupt]] void handle_invalid_tss(InterruptContext *context, uint64_t error); /*! * @brief When the CPU tried to execute an unprivileged opcode or exceeds * segmentation bounds, the GPF exception is raised. */ [[gnu::interrupt]] void handle_general_protection_fault( InterruptContext *context, uint64_t error); /*! * @brief With paging enabled, an invalid access to a memory page causes a page * fault. */ [[gnu::interrupt]] void handle_page_fault(InterruptContext *context, uint64_t error); extern "C" { // disable C++ name mangling for asm function /*! \brief Assembly interrupt handler for the keyboard. * * On keyboard interrupt, the register state is saved to and restored from the * stack. This function wraps the handle_keyboard C-function. * * \todo(12) Implement in assembly */ [[gnu::interrupt]] void handle_keyboard_asm(InterruptContext *context); /*! \brief Higher-level Interrupt handler for the keyboard. * * On keyboard interrupt, the PS2-Controller may contain a valid Key that has to * be fetched. * * \todo(12) Fetch a single key * \todo(13) Extend to use the Prologue-Epilogue pattern */ void handle_keyboard(); } /*! \brief handle_panic * * \todo(12) Trigger a kernel panic */ [[gnu::interrupt]] void handle_panic(InterruptContext *context); /*! \brief handle_timer * * \todo(15) Handle the timer interrupt */ [[gnu::interrupt]] void handle_timer(InterruptContext *context); /*! \brief handle_assassin * * Handler for the assassin IPI, i.e. a thread shall be killed. * * \todo(15) Handle the assassin interrupt (in \MPStuBS only) */ [[gnu::interrupt]] void handle_assassin(InterruptContext *context); /*! \brief handle_wakeup * * In Multicore systems, an IPI is used to wake a sleeping core. * * \todo(16) Handle the wakeup interrupt (in \MPStuBS only) */ [[gnu::interrupt]] void handle_wakeup(InterruptContext *context);