diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-09-29 17:11:15 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-09-29 17:11:15 +0200 |
| commit | a8f2e1a0edc37cd1c06447c42ff94f3370e8a6bc (patch) | |
| tree | 982df6acd03b7a13d24a9eae665d7905376e54b3 | |
| parent | cf12e4c7f618029150fbec000f0ad7f780ff721a (diff) | |
| download | kernel-a8f2e1a0edc37cd1c06447c42ff94f3370e8a6bc.tar.xz kernel-a8f2e1a0edc37cd1c06447c42ff94f3370e8a6bc.zip | |
x86_64: fix flag reading
| -rw-r--r-- | arch/x86_64/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | arch/x86_64/arch/cpu/flags.cpp | 16 | ||||
| -rw-r--r-- | arch/x86_64/arch/cpu/flags.hpp | 72 | ||||
| -rw-r--r-- | arch/x86_64/kapi/interrupts.cpp | 9 |
4 files changed, 92 insertions, 6 deletions
diff --git a/arch/x86_64/CMakeLists.txt b/arch/x86_64/CMakeLists.txt index 28199f35..59df016e 100644 --- a/arch/x86_64/CMakeLists.txt +++ b/arch/x86_64/CMakeLists.txt @@ -26,6 +26,7 @@ target_sources("x86_64" PRIVATE target_sources("x86_64" PRIVATE # CPU Initialization + "arch/cpu/flags.cpp" "arch/cpu/initialization.cpp" "arch/cpu/interrupts.cpp" "arch/cpu/interrupts.S" diff --git a/arch/x86_64/arch/cpu/flags.cpp b/arch/x86_64/arch/cpu/flags.cpp new file mode 100644 index 00000000..12a2ceee --- /dev/null +++ b/arch/x86_64/arch/cpu/flags.cpp @@ -0,0 +1,16 @@ +#include <arch/cpu/flags.hpp> + +namespace arch::cpu +{ + + auto read_flags() noexcept -> flags + { + auto rflags = flags{}; + asm volatile("pushfq\n" + "popq %0\n" + : "=r"(rflags)); + + return rflags; + } + +} // namespace arch::cpu
\ No newline at end of file diff --git a/arch/x86_64/arch/cpu/flags.hpp b/arch/x86_64/arch/cpu/flags.hpp new file mode 100644 index 00000000..d19750f4 --- /dev/null +++ b/arch/x86_64/arch/cpu/flags.hpp @@ -0,0 +1,72 @@ +#ifndef TEACHOS_ARCH_X86_64_CPU_FLAGS_HPP +#define TEACHOS_ARCH_X86_64_CPU_FLAGS_HPP + +#include <kstd/bitfield_enum.hpp> + +#include <cstdint> +#include <type_traits> + +namespace arch::cpu +{ + + enum struct flags : std::uint64_t + { + carry = 1u << 0, + parity = 1u << 2, + auxiliary_carry = 1u << 4, + zero = 1u << 6, + sign = 1u << 7, + trap = 1u << 8, + interrupt = 1u << 9, + direction = 1u << 10, + overflow = 1u << 11, + io_privilege_level_low = 1u << 12, + io_privilege_level_high = 1u << 13, + nested_task = 1u << 14, + resume = 1u << 16, + virtual_8086_mode = 1u << 17, + alignment_check = 1u << 18, + virtual_interrupt = 1u << 19, + virtual_interrupt_pending = 1u << 20, + cpuid_available = 1u << 21, + aes_key_schedule_loaded = 1u << 30, + rex32 = 1u << 31, + }; + +} // namespace arch::cpu + +template<> +struct kstd::is_bitfield_enum<arch::cpu::flags> : std::true_type +{ +}; + +namespace arch::cpu +{ + + //! Read the current CPU flags. + //! + //! @return The current set of active CPU flags. + auto read_flags() noexcept -> flags; + + //! Read a given set of CPU flags. + //! + //! @return The state of the selected flags. + template<flags Flags> + auto read_flags() noexcept -> flags + { + auto flags = read_flags(); + return flags & Flags; + } + + //! Check if a given set of CPU flags is set. + //! + //! @return @p true iff. all of the selected flags are set, @p false otherwise. + template<flags Flags> + auto check_flags() noexcept -> bool + { + return read_flags() == Flags; + } + +} // namespace arch::cpu + +#endif
\ No newline at end of file diff --git a/arch/x86_64/kapi/interrupts.cpp b/arch/x86_64/kapi/interrupts.cpp index 8d863bad..37745122 100644 --- a/arch/x86_64/kapi/interrupts.cpp +++ b/arch/x86_64/kapi/interrupts.cpp @@ -1,16 +1,13 @@ #include <kapi/interrupts.hpp> +#include <arch/cpu/flags.hpp> + namespace kapi::interrupts { auto enabled() -> bool { - auto value = false; - asm volatile("pushfq\n" - "pop %0\n" - "and $0x200, %0" - : "=r"(value)); - return value; + return arch::cpu::check_flags<arch::cpu::flags::interrupt>(); } auto enabled(bool value) -> void |
