aboutsummaryrefslogtreecommitdiff
path: root/kapi
diff options
context:
space:
mode:
Diffstat (limited to 'kapi')
-rw-r--r--kapi/CMakeLists.txt15
-rw-r--r--kapi/include/kapi/cpu.hpp104
-rw-r--r--kapi/include/kapi/interrupts.hpp61
3 files changed, 168 insertions, 12 deletions
diff --git a/kapi/CMakeLists.txt b/kapi/CMakeLists.txt
index b239adb..c9aa23f 100644
--- a/kapi/CMakeLists.txt
+++ b/kapi/CMakeLists.txt
@@ -1,22 +1,13 @@
add_library("kapi" INTERFACE)
add_library("os::kapi" ALIAS "kapi")
+file(GLOB_RECURSE KAPI_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "include/**.hpp")
+
target_sources("kapi" PUBLIC
FILE_SET HEADERS
BASE_DIRS "include"
FILES
- "include/kapi/boot_modules.hpp"
- "include/kapi/boot.hpp"
- "include/kapi/cio.hpp"
- "include/kapi/boot_module/boot_module.hpp"
- "include/kapi/boot_module/boot_module_registry.hpp"
- "include/kapi/memory.hpp"
- "include/kapi/memory/address.hpp"
- "include/kapi/memory/frame_allocator.hpp"
- "include/kapi/memory/frame.hpp"
- "include/kapi/memory/page_mapper.hpp"
- "include/kapi/memory/page.hpp"
- "include/kapi/system.hpp"
+ ${KAPI_HEADERS}
)
target_include_directories("kapi" INTERFACE
diff --git a/kapi/include/kapi/cpu.hpp b/kapi/include/kapi/cpu.hpp
index 05b84b7..c6aa6ff 100644
--- a/kapi/include/kapi/cpu.hpp
+++ b/kapi/include/kapi/cpu.hpp
@@ -1,13 +1,117 @@
#ifndef TEACHOS_KAPI_CPU_HPP
#define TEACHOS_KAPI_CPU_HPP
+#include "kapi/memory.hpp"
+
+#include <kstd/format>
+
+#include <cstdint>
+
namespace kapi::cpu
{
+
+ //! An exception originating from the CPU directly.
+ //!
+ //! Exception generally model interrupts that are synchronous to the instruction stream. This means that they do not
+ //! originate from external hardware, but rather are a product of program execution.
+ struct exception
+ {
+ //! The type of the exception, which identifies the reason for it being raised.
+ enum class type : std::uint8_t
+ {
+ //! The reason for the exception is unknown or platform-specific
+ unknown,
+ //! A page fault occurred
+ page_fault,
+ //! A memory access (either in the data or instruction stream) violated it's alignment constraints.
+ alignment_fault,
+ //! A memory access (either in the data or instruction stream) violated it's permissions.
+ memory_access_fault,
+ //! An invalid instruction was present in the instruction stream.
+ illegal_instruction,
+ //! The preconditions for the execution of an instruction were not met.
+ privilege_violation,
+ //! An arithmetic error occurred.
+ arithmetic_error,
+ //! A breakpoint was hit in the instruction stream.
+ breakpoint,
+ //! The CPU is single-stepping through the instruction stream.
+ single_step,
+ };
+
+ //! The type of this exception.
+ type type{};
+
+ //! The value of the instruction pointer at the time this exception was raised.
+ kapi::memory::linear_address instruction_pointer{};
+
+ //! The memory address that caused this exception.
+ kapi::memory::linear_address access_address{};
+
+ //! Whether the page was present at the time of the exception.
+ bool is_present{};
+
+ //! Whether the exception was caused by a write access.
+ bool is_write_access{};
+
+ //! Whether the exception was caused by a user mode access.
+ bool is_user_mode{};
+ };
+
//! @qualifier platform-defined
//! Halt the CPU.
//!
//! This function terminates execution of the kernel.
[[noreturn]] auto halt() -> void;
+
+ //! @qualifier platform-defined
+ //! Perform early CPU initialization.
+ //!
+ //! When this function returns, the CPU is in a state where interrupt could be enabled. This function must not enable
+ //! interrupts itself.
+ auto init() -> void;
+
+ //! @qualifier kernel-defined
+ //! Dispatch an exception to the appropriate handler.
+ //!
+ //! @param context The exception context.
+ //! @return Whether the exception was handled.
+ [[nodiscard]] auto dispatch(exception const & context) -> bool;
+
} // namespace kapi::cpu
+template<>
+struct kstd::formatter<enum kapi::cpu::exception::type>
+{
+ constexpr auto parse(kstd::format_parse_context & ctx) -> decltype(ctx.begin())
+ {
+ return ctx.begin();
+ }
+
+ constexpr auto format(enum kapi::cpu::exception::type type, kstd::format_context & ctx) const -> void
+ {
+ switch (type)
+ {
+ case kapi::cpu::exception::type::unknown:
+ return ctx.push("unknown");
+ case kapi::cpu::exception::type::page_fault:
+ return ctx.push("page fault");
+ case kapi::cpu::exception::type::alignment_fault:
+ return ctx.push("alignment fault");
+ case kapi::cpu::exception::type::memory_access_fault:
+ return ctx.push("memory access fault");
+ case kapi::cpu::exception::type::illegal_instruction:
+ return ctx.push("illegal instruction");
+ case kapi::cpu::exception::type::privilege_violation:
+ return ctx.push("privilege violation");
+ case kapi::cpu::exception::type::arithmetic_error:
+ return ctx.push("arithmetic error");
+ case kapi::cpu::exception::type::breakpoint:
+ return ctx.push("breakpoint");
+ case kapi::cpu::exception::type::single_step:
+ return ctx.push("single step");
+ }
+ }
+};
+
#endif
diff --git a/kapi/include/kapi/interrupts.hpp b/kapi/include/kapi/interrupts.hpp
new file mode 100644
index 0000000..f72ef8c
--- /dev/null
+++ b/kapi/include/kapi/interrupts.hpp
@@ -0,0 +1,61 @@
+#ifndef TEACHOS_KAPI_INTERRUPTS_HPP
+#define TEACHOS_KAPI_INTERRUPTS_HPP
+
+#include <cstdint>
+
+namespace kapi::interrupts
+{
+
+ enum class status : bool
+ {
+ unhandled,
+ handled,
+ };
+
+ //! The interface for all interrupt handlers.
+ struct handler
+ {
+ virtual ~handler() = default;
+
+ //! Handle an interrupt with the given IRQ number.
+ //
+ //! This function will be called by the kernel in an interrupt context. As such, the function should complete its
+ //! task quickly and must take care when acquiring globally shared locks.
+ //!
+ //! @param irq_number The identifier of the interrupt request that triggered the handler.
+ //! @return status::handled if the handler successfully handled the interrupt, status::unhandled otherwise.
+ virtual auto handle_interrupt(std::uint32_t irq_number) -> status = 0;
+ };
+
+ //! @qualifier platform-defined
+ //! Enable external interrupts.
+ auto enable() -> void;
+
+ //! @qualifier platform-defined
+ //! Disable external interrupts.
+ auto disable() -> void;
+
+ //! @qualifier kernel-defined
+ //! Register an interrupt handler for the given IRQ number.
+ //!
+ //! @param irq_number The IRQ number to register the handler for.
+ //! @param handler The interrupt handler to register.
+ auto register_handler(std::uint32_t irq_number, handler & handler) -> void;
+
+ //! @qualifier kernel-defined
+ //! Unregister a previously registered interrupt handler.
+ //!
+ //! @param irq_number The IRQ number to unregister the handler for.
+ //! @param handler The interrupt handler to unregister.
+ auto unregister_handler(std::uint32_t irq_number, handler & handler) -> void;
+
+ //! @qualifier kernel-defined
+ //! Dispatch an interrupt to all registered handlers.
+ //!
+ //! @param irq_number The IRQ number to dispatch.
+ //! @return status::handled if the interrupt was handled by at least one handler, status::unhandled otherwise.
+ auto dispatch(std::uint32_t irq_number) -> status;
+
+} // namespace kapi::interrupts
+
+#endif \ No newline at end of file