diff options
| author | Lukas Oesch <lukas.oesch@ost.ch> | 2026-06-10 10:40:46 +0200 |
|---|---|---|
| committer | Lukas Oesch <lukas.oesch@ost.ch> | 2026-06-10 10:40:46 +0200 |
| commit | 33abd5cf264cb9e34121082105b0bc17b3cf7a36 (patch) | |
| tree | 36b15d53fea04f4f9d9af817100f7ad013bd9b5c /arch/x86_64/pre | |
| parent | d01caf1c4aef3c89c68b9d1cc9fe56445f0860b5 (diff) | |
| parent | 7e27130c342b7299a1d2188a7192a7f17b5ac2ad (diff) | |
| download | kernel-33abd5cf264cb9e34121082105b0bc17b3cf7a36.tar.xz kernel-33abd5cf264cb9e34121082105b0bc17b3cf7a36.zip | |
Merge of BA-FS26 branch into develop
See merge request teachos/kernel!49
Diffstat (limited to 'arch/x86_64/pre')
36 files changed, 0 insertions, 1357 deletions
diff --git a/arch/x86_64/pre/include/arch/context_switching/interrupt_descriptor_table/gate_descriptor.hpp b/arch/x86_64/pre/include/arch/context_switching/interrupt_descriptor_table/gate_descriptor.hpp deleted file mode 100644 index 07110c8..0000000 --- a/arch/x86_64/pre/include/arch/context_switching/interrupt_descriptor_table/gate_descriptor.hpp +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_INTERRUPT_DESCRIPTOR_TABLE_GATE_DESCRIPTOR_HPP -#define TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_INTERRUPT_DESCRIPTOR_TABLE_GATE_DESCRIPTOR_HPP - -#include "arch/context_switching/interrupt_descriptor_table/idt_flags.hpp" -#include "arch/context_switching/interrupt_descriptor_table/ist_offset.hpp" -#include "arch/context_switching/interrupt_descriptor_table/segment_selector.hpp" - -#include <bitset> -#include <cstdint> - -namespace teachos::arch::context_switching::interrupt_descriptor_table -{ - __extension__ typedef __int128 int128_t; - __extension__ typedef unsigned __int128 uint128_t; - - /** - * @brief Defines helper function for all states and the actual data the gate descriptor can have. - */ - struct [[gnu::packed]] gate_descriptor - { - /** - * @brief Default Constructor. - */ - gate_descriptor() = default; - - /** - * @brief Constructor. - * - * @note Created gate descriptor copies the given bytes into these components ending with a 32 bit reserved - * field that has to be used, because the 64-bit gate descriptor needs to be big enough for two 32-bit gate - * descriptor. - * - 16 bit Segment Selector - * - 3 bit Interrupt Stack Table Offset - * - 8 bit Type and Flags - * - 64 bit Offset - * - * @param flags Copies the bits set from the given data into the individual components of a gate - * descriptor. - */ - explicit gate_descriptor(uint128_t flags); - - /** - * @brief Constructor. - * - * @param selector, ist, flags, offset Copies the bits set from the given data into the individual components of - * a gate descriptor. - */ - gate_descriptor(segment_selector selector, ist_offset ist, idt_flags flags, uint64_t offset); - - /** - * @brief Allows to compare the underlying bits of two instances. - * - * @param other Other instance that we want to compare with. - * @return Whether the underlying set bits of both types are the same. - */ - auto operator==(gate_descriptor const & other) const -> bool = default; - - private: - // The order in private variables starts for the first variable being the rightmost bit. - uint16_t _offset_1 = {}; ///< Lower 16 bits of handler function address (0 - 15) - segment_selector _selector = {}; ///< Segment selector (16 - 31) - ist_offset _ist = {}; ///< Interrupt Stack Table offset (32 - 39) - idt_flags _flags = {}; ///< Gate Type and Flags (40 - 47) - uint64_t _offset_2 : 48 = {}; ///< Upper 48 bits of handler function address (48 - 95) - uint32_t : 32; ///< Reserved field used to ensure this struct is 128 bits big (96 - 127) - }; -} // namespace teachos::arch::context_switching::interrupt_descriptor_table - -#endif // TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_INTERRUPT_DESCRIPTOR_TABLE_GATE_DESCRIPTOR_HPP diff --git a/arch/x86_64/pre/include/arch/context_switching/interrupt_descriptor_table/idt_flags.hpp b/arch/x86_64/pre/include/arch/context_switching/interrupt_descriptor_table/idt_flags.hpp deleted file mode 100644 index 5104c36..0000000 --- a/arch/x86_64/pre/include/arch/context_switching/interrupt_descriptor_table/idt_flags.hpp +++ /dev/null @@ -1,81 +0,0 @@ - -#ifndef TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_INTERRUPT_DESCRIPTOR_TABLE_IDT_FLAGS_HPP -#define TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_INTERRUPT_DESCRIPTOR_TABLE_IDT_FLAGS_HPP - -#include <bitset> -#include <cstdint> - -namespace teachos::arch::context_switching::interrupt_descriptor_table -{ - /** - * @brief Defines helper function for all states that the access byte field of a segment descriptor can - * have. - */ - struct [[gnu::packed]] idt_flags - { - /** - * @brief Possible set bits in our underlying bits and the meaning when they are set. - */ - enum bitset : uint8_t - { - INTERRUPT_GATE = 0b01110, ///< The actual type of gate segment is a interrupt gate. - TRAP_GATE = 0b01111, ///< The actual type of gate segment is a trap gate. - DESCRIPTOR_LEVEL_KERNEL = - 0U << 5U, ///< Highest privileged level used by the kernel to allow for full access of resources. - DESCRIPTOR_LEVEL_ADMIN = - 1U << 5U, ///< Restricts access to own application and thoose of lower privilege. Should only be used if more - ///< than two privilege levels are required, otherwise using Level 3 and Level 0 is recommended. - DESCRIPTOR_LEVEL_PRIVILEGED_USER = - 2U << 5U, ///< Restricts access to own application and thoose of lower privilege. Should only be used if more - ///< than two privilege levels are required, otherwise using Level 3 and Level 0 is recommended. - DESCRIPTOR_LEVEL_USER = 3U << 5U, ///< Restricts access to only application and their specific memory. - PRESENT = 1U << 7U, ///< Present bit; Allows an entry to refer to a valid segment. - ///< Must be set (1) for any valid segment. - }; - - /** - * @brief Default Constructor. - */ - idt_flags() = default; - - /** - * @brief Constructor. - * - * @param flags Allows to set flags for the access byte field using the unscoped enum contained in this class, used - * to allow for direct integer conversion. This value is saved and can later be used to check whether certain flags - * are enabled or not using contains_flags method. - */ - idt_flags(uint8_t flags); - - /** - * @brief Checks if the given std::bitset is a subset or equivalent to the underlying data. - * - * @note Meaning that all bits that are set in the given std::bitset also have to be set in the underlyng - * data. Any additional bits that are set are not relevant. - * - * @param other Flags that we want to compare against and check if the underlying data has the same bits set. - * @return Whether the given flags are a subset or equivalent with the underlying data. - */ - auto contains_flags(std::bitset<8U> other) const -> bool; - - /** - * @brief Allows to compare the underlying bits of two instances. - * - * @param other Other instance that we want to compare with. - * @return Whether the underlying set bits of both types are the same. - */ - auto operator==(idt_flags const & other) const -> bool = default; - - /** - * @brief Combines all bits that are set in the std::bitset flags with the bits already set in the underlying data. - * - * @param other Additional bits that should be set. - */ - auto operator|=(std::bitset<8U> other) -> void; - - private: - uint8_t _flags = {}; ///< Underlying bits used to read the flags from. - }; -} // namespace teachos::arch::context_switching::interrupt_descriptor_table - -#endif // TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_INTERRUPT_DESCRIPTOR_TABLE_IDT_FLAGS_HPP
\ No newline at end of file diff --git a/arch/x86_64/pre/include/arch/context_switching/interrupt_descriptor_table/interrupt_descriptor_table.hpp b/arch/x86_64/pre/include/arch/context_switching/interrupt_descriptor_table/interrupt_descriptor_table.hpp deleted file mode 100644 index b388e0e..0000000 --- a/arch/x86_64/pre/include/arch/context_switching/interrupt_descriptor_table/interrupt_descriptor_table.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_INTERRUPT_DESCRIPTOR_TABLE_INTERRUPT_DESCRIPTOR_TABLE_HPP -#define TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_INTERRUPT_DESCRIPTOR_TABLE_INTERRUPT_DESCRIPTOR_TABLE_HPP - -#include "arch/context_switching/interrupt_descriptor_table/interrupt_descriptor_table_pointer.hpp" - -namespace teachos::arch::context_switching::interrupt_descriptor_table -{ - /** - * @brief Updates the IDTR with the created interrupt descriptor table. If it has not been created yet this - * method will create it. - */ - auto update_interrupt_descriptor_table_register() -> void; - - /** - * @brief Creates the interrupt descriptor table, with the minimum required configuration. If this method is called - * more than once, the previously created instance is returned instead. - * - * @return Reference to the created interrupt_descriptor_table. - */ - auto get_or_create_interrupt_descriptor_table() -> interrupt_descriptor_table &; - -} // namespace teachos::arch::context_switching::interrupt_descriptor_table - -#endif // TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_INTERRUPT_DESCRIPTOR_TABLE_INTERRUPT_DESCRIPTOR_TABLE_HPP diff --git a/arch/x86_64/pre/include/arch/context_switching/interrupt_descriptor_table/interrupt_descriptor_table_pointer.hpp b/arch/x86_64/pre/include/arch/context_switching/interrupt_descriptor_table/interrupt_descriptor_table_pointer.hpp deleted file mode 100644 index 7fe933b..0000000 --- a/arch/x86_64/pre/include/arch/context_switching/interrupt_descriptor_table/interrupt_descriptor_table_pointer.hpp +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_INTERRUPT_DESCRIPTOR_TABLE_INTERRUPT_DESCRIPTOR_TABLE_POINTER_HPP -#define TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_INTERRUPT_DESCRIPTOR_TABLE_INTERRUPT_DESCRIPTOR_TABLE_POINTER_HPP - -#include "arch/context_switching/interrupt_descriptor_table/gate_descriptor.hpp" -#include "arch/stl/vector.hpp" - -namespace teachos::arch::context_switching::interrupt_descriptor_table -{ - using interrupt_descriptor_table = stl::vector<gate_descriptor>; - - /** - * @brief Represents a pointer to the Interrupt Descriptor Table (IDT). - * - * This structure is used to store the base address and length of the IDT. - */ - struct [[gnu::packed]] interrupt_descriptor_table_pointer - { - /** - * @brief Default constructor. - */ - interrupt_descriptor_table_pointer() = default; - - /** - * @brief Constructor. - */ - interrupt_descriptor_table_pointer(uint16_t table_length, gate_descriptor * address); - - /** - * @brief Defaulted three-way comparsion operator. - */ - auto operator<=>(interrupt_descriptor_table_pointer const & other) const -> std::strong_ordering = default; - - private: - uint16_t table_length = {}; ///< The amount of segment descriptor entries in the global descriptor table - 1. - gate_descriptor * address = {}; ///< Non-owning pointer to the IDT base address. - }; - -} // namespace teachos::arch::context_switching::interrupt_descriptor_table - -#endif // TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_INTERRUPT_DESCRIPTOR_TABLE_INTERRUPT_DESCRIPTOR_TABLE_POINTER_HPP diff --git a/arch/x86_64/pre/include/arch/context_switching/interrupt_descriptor_table/ist_offset.hpp b/arch/x86_64/pre/include/arch/context_switching/interrupt_descriptor_table/ist_offset.hpp deleted file mode 100644 index e45bcf4..0000000 --- a/arch/x86_64/pre/include/arch/context_switching/interrupt_descriptor_table/ist_offset.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_INTERRUPT_DESCRIPTOR_TABLE_IST_OFFSET_HPP -#define TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_INTERRUPT_DESCRIPTOR_TABLE_IST_OFFSET_HPP - -#include <bitset> -#include <cstdint> - -namespace teachos::arch::context_switching::interrupt_descriptor_table -{ - /** - * @brief Defines helper function for all states that the interrupt stack table offset field of a gate descriptor can - * have. Is automatically increased to one byte in size, to include the following 5 reserved bits in the gate - * descriptor. - */ - struct [[gnu::packed]] ist_offset - { - /** - * @brief Default Constructor. - */ - ist_offset() = default; - - /** - * @brief Constructor. - * - * @param offset Offset into the interrupt stack table. A value of of 0 means we do not switch stacks, whereas 1 - 7 - * mean we switch to the n-th stack in the Interrupt Stack Table, contained in the TSS if the gate descriptor that - * contains this field is called. - */ - ist_offset(uint8_t offset); - - /** - * @brief Allows to compare the underlying set bits of two instances. - * - * @param other Other instance that we want to compare with. - * @return Whether the underlying set bits of both types are the same. - */ - auto operator==(ist_offset const & other) const -> bool = default; - - private: - uint8_t _ist : 3 = {}; ///< Offset into the interrupt stack table. A value of of 0 means we do not switch stacks, - ///< whereas 1 - 7 mean we switch to the n-th stack in the Interrupt Stack Table, contained - ///< in the TSS if the gate descriptor that contains this field is called. - }; -} // namespace teachos::arch::context_switching::interrupt_descriptor_table - -#endif // TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_INTERRUPT_DESCRIPTOR_TABLE_IST_OFFSET_HPP diff --git a/arch/x86_64/pre/include/arch/context_switching/interrupt_descriptor_table/segment_selector.hpp b/arch/x86_64/pre/include/arch/context_switching/interrupt_descriptor_table/segment_selector.hpp deleted file mode 100644 index ea8c145..0000000 --- a/arch/x86_64/pre/include/arch/context_switching/interrupt_descriptor_table/segment_selector.hpp +++ /dev/null @@ -1,105 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_INTERRUPT_DESCRIPTOR_TABLE_SEGMENT_SELECTOR_HPP -#define TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_INTERRUPT_DESCRIPTOR_TABLE_SEGMENT_SELECTOR_HPP - -#include <bitset> -#include <cstdint> - -namespace teachos::arch::context_switching::interrupt_descriptor_table -{ - /** - * @brief Represents a segment selector in the x86_64 architecture, which points to a valid code segment in the global - * descriptor table. - * - * A segment selector is a 16-bit identifier used to select a segment descriptor - * from the Global Descriptor Table (GDT) or the Local Descriptor Table (LDT). - * It contains an index, a table indicator (TI), and a requested privilege level (RPL). - */ - struct [[gnu::packed]] segment_selector - { - /** - * @brief Possible set bits in our underlying bits and the meaning when they are set. - */ - enum bitset : uint8_t - { - REQUEST_LEVEL_KERNEL = - 0U << 0U, ///< Highest privileged level used by the kernel to allow for full access of resources. - REQUEST_LEVEL_ADMIN = - 1U << 0U, ///< Restricts access to own application and thoose of lower privilege. Should only be used if more - ///< than two privilege levels are required, otherwise using Level 3 and Level 0 is recommended. - REQUEST_LEVEL_PRIVILEGED_USER = - 2U << 0U, ///< Restricts access to own application and thoose of lower privilege. Should only be used if more - ///< than two privilege levels are required, otherwise using Level 3 and Level 0 is recommended. - REQUEST_LEVEL_USER = 3U << 0U, ///< Restricts access to only application and their specific memory. - LOCAL_DESCRIPTOR_TABLE = 1U << 2U, ///< Wheter the index referes to an entry in the local or global descriptor - ///< table. If enabled the index points to a local descriptor table, if it is - ///< cleared it referes to a global descriptor table instead. - }; - - /** - * @brief Default constructor. - */ - segment_selector() = default; - - /** - * @brief Constructor. - * - * @param index Index into the local or global descriptor table. Processor multiplies the index value by 8 (number - * of bytes in 32-bit segment descriptor) and adds the result to the base GDT or LDT address. - * @param flags Allows to set flags for the flags field using the unscoped enum contained in this class, used to - * allow for direct integer conversion. - */ - constexpr segment_selector(uint16_t index, uint8_t flags) - : _flags(flags) - , _index(index) - { - // Nothing to do. - } - - /** - * @brief Checks if the given std::bitset is a subset or equivalent to the underlying data. - * - * @note Meaning that all bits that are set in the given std::bitset also have to be set in the underlyng - * data. Any additional bits that are set are not relevant. - * - * @param other Flags that we want to compare against and check if the underlying data has the same bits set. - * @return Whether the given flags are a subset or equivalent with the underlying data. - */ - auto contains_flags(std::bitset<3U> other) const -> bool; - - /** - * @brief Gets the index into the global descriptor table or the local descriptor table this segment selector is - * pointing too. - * - * @return Underlying value of the index field, bit 3 - 16. - */ - [[gnu::section(".user_text")]] - auto get_index() const -> uint16_t; - - /** - * @brief Defaulted three-way comparsion operator. - */ - auto operator<=>(segment_selector const & other) const -> std::strong_ordering = default; - - /** - * @brief Combines all bits that are set in the std::bitset flags with the bits already set in the underlying data. - * - * @param other Additional bits that should be set. - */ - auto operator|=(std::bitset<3U> other) -> void; - - /** - * @brief Cast the underlying data into a combined 16-bit form, that contains all data. - * - * @return Underlying value combined into it's full size. - */ - operator uint16_t() const; - - private: - uint8_t _flags : 3 = {}; ///< Underlying bits used to read the flags from. - uint16_t _index - : 13 = {}; ///< Index into the local or global descriptor table. Processor multiplies the index value by 16 - ///< (number of bytes in segment descriptor) and adds the result to the base address. - }; -} // namespace teachos::arch::context_switching::interrupt_descriptor_table - -#endif // TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_INTERRUPT_DESCRIPTOR_TABLE_SEGMENT_SELECTOR_HPP diff --git a/arch/x86_64/pre/include/arch/context_switching/main.hpp b/arch/x86_64/pre/include/arch/context_switching/main.hpp deleted file mode 100644 index f8477ea..0000000 --- a/arch/x86_64/pre/include/arch/context_switching/main.hpp +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_MAIN_HPP -#define TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_MAIN_HPP - -#include "arch/context_switching/interrupt_descriptor_table/interrupt_descriptor_table.hpp" -#include "arch/context_switching/segment_descriptor_table/global_descriptor_table.hpp" - -namespace teachos::arch::context_switching -{ - /** - * @brief Contains the references to the tables required for context switching - */ - struct descriptor_tables - { - segment_descriptor_table::global_descriptor_table & gdt; ///< Reference to the global descriptor table. - interrupt_descriptor_table::interrupt_descriptor_table & idt; ///< Reference to the interrupt descriptor table. - }; - - /** - * @brief Creates the Interrupt Descriptor Table and Global Descriptor Table as a static variable the first time this - * method is called and update IDTR and GDTR registers values. - * - * @note Subsequent calls after the first one, will simply return the previously created tables, but not update the - * registers again. - * - * @return References to the statically created Interrupt Descriptor and Global Descriptor Table. - */ - auto initialize_descriptor_tables() -> descriptor_tables; - - /** - * @brief Switches from the current Kernel Mode (Level 0) to User Mode (Level 3). Will simply use predefined Segment - * Selectors for the User Data and User Code Segment, which are Index 3 and 4 in the GDT respectively. - */ - auto switch_to_user_mode() -> void; - - /** - * @brief Switches from the current Code and Data Segment to the given Code and Data Segment. - * - * @note This method will additionally call initialize_descriptor_tables, to ensure the GDTR and IDTR have been setup - * correctly before attempting to switch the context. This switch is achieved using a far return, which will once - * executed call the given void function. - * - * @param data_segment Data Segment that the SS, DS; ES, FS and GS register will be set too. - * @param code_segment Code Segment that the CS register will be set too. - * @param return_function Function that will be called once the switch has been achieved. - */ - auto switch_context(interrupt_descriptor_table::segment_selector data_segment, - interrupt_descriptor_table::segment_selector code_segment, void (*return_function)()) -> void; - -} // namespace teachos::arch::context_switching - -#endif // TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_MAIN_HPP diff --git a/arch/x86_64/pre/include/arch/context_switching/syscall/main.hpp b/arch/x86_64/pre/include/arch/context_switching/syscall/main.hpp deleted file mode 100644 index f507c61..0000000 --- a/arch/x86_64/pre/include/arch/context_switching/syscall/main.hpp +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SYSCALL_MAIN_HPP -#define TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SYSCALL_MAIN_HPP - -#include <cstdint> - -namespace teachos::arch::context_switching::syscall -{ - /** - * @brief Possible syscall implementation that should actually be called. - * - * @note Attempts to reflect the Linux interface partially. See https://filippo.io/linux-syscall-table/ for more - * information. - */ - enum class type : uint64_t - { - WRITE = 1U, ///< Loads the arg_0 parameter as an address pointing to a const char array, which will then be printed - ///< onto the VGA buffer screen. - EXPAND_HEAP = 2U, /// Expands the User Heap by additonally mapping 100 KiB of virtual page memory. Ignores the - /// parameters and uses them as out parameters instead, where arg_0 is the start of the newly - /// mapped heap area and arg_1 is the size of the entire area. Can be less than 100 KiB if less - /// space remains. - ASSERT = 3U, /// Loads the arg_0 parameter as a boolean which needs to be true or it will print the message in - /// arg_1 parameter onto the VGA buffer screen, keep it as a nullptr if it shouldn't print anything - /// and then it halts the further execution of the application. - }; - - /** - * @brief Possible error codes that can be returned by the different syscall methods called depending on the type - * enum. - */ - enum class error : uint8_t - { - OK = 0U, ///< No error occured in syscall. - OUT_OF_MEMORY = 1U, ///< Expanding heap failed because we have run out of mappable virtual address space. - }; - - /** - * @brief Allows to convert the error enum type into a boolean directly. Where any code besides 0 being no error, will - * return true. The remaining errors return true. - * - * @param e Error code that was returned by the syscall. - * @return Return true if there was no error and false otherwise. - */ - constexpr bool operator!(error e) - { - return e == error::OK; - } - - /** - * @brief Maximum amount of arguments that can be passed to a syscall. Default value is 0 and arguments are only ever - * used depending on the actual enum type and if the method requires thoose parameters. - */ - struct arguments - { - uint64_t arg_0{}; ///< First optional paramter to the syscall representing the RDI register. - uint64_t arg_1{}; ///< Second optional paramter to the syscall representing the RSI register. - uint64_t arg_2{}; ///< Third optional paramter to the syscall representing the RDX register. - uint64_t arg_3{}; ///< Fourth optional paramter to the syscall representing the R10 register. - uint64_t arg_4{}; ///< Fifth optional paramter to the syscall representing the R8 register. - uint64_t arg_5{}; ///< Sixth optional paramter to the syscall representing the R9 register. - }; - - /** - * @brief Response of a systemcall always containin an error code, signaling if the syscall even succeeded or not. - * Additionally it may contain up to 6 return values in the values struct. - */ - struct response - { - error error_code; ///< Error code returned by the syscall. If it failed all the values will be 0. - arguments values = {}; ///< Optional return values of the syscall implementation. - }; - - /** - * @brief Calls the method associated with the given syscall number and passes the given optional arguments to it, - * over the RDI, RSI, RDX, R10, R8 and R9 register. - * - * @param syscall_number Syscall method that should be called. See enum values in type for possible implemented - * methods. - * @param args Optional arguments passable to the different syscall methods, called depending on the syscall_number. - * Not passing the required parameters to the method, will result in passing 0 instead, which might make the fail or - * not function correctly. - * @return The syscall implementation always returns a bool-convertable error code converting to true if the syscall - * failed or false if it didn't. Additionally it might pase additional values besides the error code, they will be set - * in the arguments struct. So the value can be read and used for further processing. - */ - [[gnu::section(".user_text")]] - auto syscall(type syscall_number, arguments args = {}) -> response; - -} // namespace teachos::arch::context_switching::syscall - -#endif // TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SYSCALL_MAIN_HPP diff --git a/arch/x86_64/pre/include/arch/context_switching/syscall/syscall_enable.hpp b/arch/x86_64/pre/include/arch/context_switching/syscall/syscall_enable.hpp deleted file mode 100644 index 8cb468a..0000000 --- a/arch/x86_64/pre/include/arch/context_switching/syscall/syscall_enable.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SYSCALL_SYSCALL_ENABLE_HPP -#define TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SYSCALL_SYSCALL_ENABLE_HPP - -namespace teachos::arch::context_switching::syscall -{ - /** - * @brief Enables and sets up internal CPU registers to allow for syscall to function correctly and switch context - * temporarily back to the kernel level. - * - * @note Configures the Model Specific Register required by syscall (LSTAR, FMASK, STAR) with the correct values so - * that the syscall_handler is called and sets the System Call Extension bit on the EFER flags to allow for syscall - * to be used. - */ - auto enable_syscall() -> void; - -} // namespace teachos::arch::context_switching::syscall - -#endif // TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SYSCALL_SYSCALL_ENABLE_HPP diff --git a/arch/x86_64/pre/include/arch/context_switching/syscall/syscall_handler.hpp b/arch/x86_64/pre/include/arch/context_switching/syscall/syscall_handler.hpp deleted file mode 100644 index 2e7bcd1..0000000 --- a/arch/x86_64/pre/include/arch/context_switching/syscall/syscall_handler.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SYSCALL_SYSCALL_HANDLER_HPP -#define TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SYSCALL_SYSCALL_HANDLER_HPP - -#include <cstdint> - -namespace teachos::arch::context_switching::syscall -{ - /** - * @brief Handler for SYSCALL instruction. Calls a specific implementation based - * on the register RAX. - * - * @return Returns with LEAVE, SYSRETQ - */ - auto syscall_handler() -> void; - -} // namespace teachos::arch::context_switching::syscall - -#endif // TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SYSCALL_SYSCALL_HANDLER_HPP diff --git a/arch/x86_64/pre/include/arch/interrupt_handling/generic_interrupt_handler.hpp b/arch/x86_64/pre/include/arch/interrupt_handling/generic_interrupt_handler.hpp deleted file mode 100644 index 15b35c1..0000000 --- a/arch/x86_64/pre/include/arch/interrupt_handling/generic_interrupt_handler.hpp +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_INTERRUPT_HANDLING_GENERIC_INTERRUPT_HANDLER_HPP -#define TEACHOS_ARCH_X86_64_INTERRUPT_HANDLING_GENERIC_INTERRUPT_HANDLER_HPP - -#include <cstdint> - -namespace teachos::arch::interrupt_handling -{ - /** - * @brief Represents the CPU state during an interrupt. - * - * Some interrupts push an error code, while others do not. The full list - * of which vector number contains the error code can be found here: https://wiki.osdev.org/Exceptions - */ - struct [[gnu::packed]] interrupt_frame - { - // uint64_t error_code; ///< Error code only pushed by some exceptions, therefore it is commented out. - uint64_t ip; ///< Instruction pointer at the time of the interrupt. - uint64_t cs; ///< Code segment selector indicating privilege level. - uint64_t flags; ///< CPU flags (RFLAGS) storing processor state. - uint64_t sp; ///< Stack pointer at the time of the interrupt. - uint64_t ss; ///< Stack segment selector, usually unused in 64-bit mode. - }; - - /** - * @brief Generic interrupt handler function. - * - * @param frame Pointer to the interrupt frame containing CPU state. - */ - [[gnu::interrupt]] - auto generic_interrupt_handler(interrupt_frame * frame) -> void; - -} // namespace teachos::arch::interrupt_handling - -#endif // TEACHOS_ARCH_X86_64_INTERRUPT_HANDLING_GENERIC_INTERRUPT_HANDLER_HPP diff --git a/arch/x86_64/pre/include/arch/kernel/cpu/call.hpp b/arch/x86_64/pre/include/arch/kernel/cpu/call.hpp deleted file mode 100644 index 3c43304..0000000 --- a/arch/x86_64/pre/include/arch/kernel/cpu/call.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_KERNEL_CPU_JMP_HPP -#define TEACHOS_ARCH_X86_64_KERNEL_CPU_JMP_HPP - -#include "arch/context_switching/interrupt_descriptor_table/segment_selector.hpp" - -#include <cstdint> - -namespace teachos::arch::kernel::cpu -{ - /** - * @brief Far Pointer. Address to function located in another code segment. - */ - struct far_pointer - { - void (*function)(); ///< Address of the function we want to call. (0-63) - context_switching::interrupt_descriptor_table::segment_selector - selector; ///< Segment selector pointing to the GDT entry we want to load into register CS. (64-79) - }; - - /** - * @brief Far call - A call to an instruction located in a different segment than the current code segment but at the - * same privilege level. - * - * @param pointer 64-bit operand size far pointer that we want to call. - */ - auto call(far_pointer pointer) -> void; - -} // namespace teachos::arch::kernel::cpu - -#endif // TEACHOS_ARCH_X86_64_KERNEL_CPU_JMP_HPP diff --git a/arch/x86_64/pre/include/arch/kernel/cpu/idtr.hpp b/arch/x86_64/pre/include/arch/kernel/cpu/idtr.hpp deleted file mode 100644 index cb800d0..0000000 --- a/arch/x86_64/pre/include/arch/kernel/cpu/idtr.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_KERNEL_CPU_IDTR_HPP -#define TEACHOS_ARCH_X86_64_KERNEL_CPU_IDTR_HPP - -#include "arch/context_switching/interrupt_descriptor_table/interrupt_descriptor_table_pointer.hpp" - -#include <bitset> -#include <cstdint> - -namespace teachos::arch::kernel::cpu -{ - /** - * @brief Returns the value in the IDTR register. - * - * @return Value of IDTR register. - */ - auto store_interrupt_descriptor_table() - -> context_switching::interrupt_descriptor_table::interrupt_descriptor_table_pointer; - - /** - * @brief Loads the interrupt_descriptor_table_pointer into the interrupt descriptor table register (IDTR). - */ - auto load_interrupt_descriptor_table( - context_switching::interrupt_descriptor_table::interrupt_descriptor_table_pointer const & idt_pointer) -> void; - -} // namespace teachos::arch::kernel::cpu - -#endif // TEACHOS_ARCH_X86_64_KERNEL_CPU_IDTR_HPP diff --git a/arch/x86_64/pre/include/arch/kernel/cpu/if.hpp b/arch/x86_64/pre/include/arch/kernel/cpu/if.hpp deleted file mode 100644 index 48707dc..0000000 --- a/arch/x86_64/pre/include/arch/kernel/cpu/if.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_KERNEL_CPU_IF_HPP -#define TEACHOS_ARCH_X86_64_KERNEL_CPU_IF_HPP - -namespace teachos::arch::kernel::cpu -{ - /** - * @brief Sets the interrupt flag (IF) in the EFLAGS register. - * This allows the processor to respond to maskable hardware interrupts. - */ - auto set_interrupt_flag() -> void; - - /** - * @brief Clears the interrupt flag (IF) in the EFLAGS register. - * This will stop the processor to respond to maskable hardware interrupts and needs to be done before changing the - * Interrupt Descriptor Table with lidt. - */ - auto clear_interrupt_flag() -> void; - -} // namespace teachos::arch::kernel::cpu - -#endif // TEACHOS_ARCH_X86_64_KERNEL_CPU_IF_HPP diff --git a/arch/x86_64/pre/include/arch/kernel/cpu/msr.hpp b/arch/x86_64/pre/include/arch/kernel/cpu/msr.hpp deleted file mode 100644 index 99d6378..0000000 --- a/arch/x86_64/pre/include/arch/kernel/cpu/msr.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_KERNEL_CPU_NXE_HPP -#define TEACHOS_ARCH_X86_64_KERNEL_CPU_NXE_HPP - -#include <bitset> -#include <cstdint> - -namespace teachos::arch::kernel::cpu -{ - /** - * @brief Important flags that can be writen into the Extended Feature Enable Register (EFER). - * - * @note EFER is a model-specific register allowing to configure CPU extensions. Only the most important extensions - * are listed below, the rest are excluded for brevity. See https://en.wikipedia.org/wiki/Control_register#EFER for - * more information. - */ - enum class efer_flags : uint64_t - { - SCE = 1UL << 0UL, ///< System Call Extensions. - LME = 1UL << 8UL, ///< Long Mode Enabled. - LMA = 1UL << 10UL, ///< Long Mode Active. - NXE = 1UL << 11UL, ///< No-Execute Enable. - SVME = 1UL << 12UL, ///< Secure Virtual Machine Enable. - LMSLE = 1UL << 13UL, ///< Long Mode Segment Limit Enable. - FFXSR = 1UL << 14UL, ///< Fast FXSAVE/FXSTOR. - TCE = 1UL << 15UL, ///< Translation Cache Extension. - }; - - /** - * @brief Reads a 64-bit from the Model-Specific Register (MSR). - * - * @note This function reads the value of an MSR specified by the given address. It combines the lower and upper - * 32-bits of the MSR value read using the 'rdmsr' instruction and returns it as a 64-bit unsigned integer. - * - * @param msr The address of the MSR to read. - * @return The 64-bit value read from the MSR. - */ - auto read_msr(uint32_t msr) -> uint64_t; - - /** - * @brief Writes a 64-bit value to a Model-Specific Register (MSR). - * - * @note This function writes a 64-bit value to the MSR specified by the given address. - * It splits the 64-bit value into two 32-bit parts and writes them using the - * `wrmsr` instruction. - * - * @param msr The address of the MSR to write to. - * @param new_value The 64-bit value to write to the MSR. - */ - auto write_msr(uint32_t msr, uint64_t new_value) -> void; - - /** - * @brief Sets a specific bit in the Extended Feature Enable Register (EFER), which is a Model-Specific Register - * (MSR). - * - * @note This function reads the current value of the EFER register, ORs the specified - * bit with the current value, and writes the updated value back to the EFER register. - * - * @param flag The flag to set in the EFER register. - */ - auto set_efer_bit(efer_flags flag) -> void; - -} // namespace teachos::arch::kernel::cpu - -#endif // TEACHOS_ARCH_X86_64_KERNEL_CPU_NXE_HPP
\ No newline at end of file diff --git a/arch/x86_64/pre/include/arch/kernel/cpu/tr.hpp b/arch/x86_64/pre/include/arch/kernel/cpu/tr.hpp deleted file mode 100644 index 7c856f1..0000000 --- a/arch/x86_64/pre/include/arch/kernel/cpu/tr.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_KERNEL_CPU_TR_HPP -#define TEACHOS_ARCH_X86_64_KERNEL_CPU_TR_HPP - -#include <bitset> -#include <cstdint> - -namespace teachos::arch::kernel::cpu -{ - - /** - * @brief Returns the value in the LTR register. - * - * @return Value of LTR register. - */ - auto store_task_register() -> uint16_t; - - /** - * @brief Loads the gdt offset to the tss segment descriptor into the task register (TR). - */ - auto load_task_register(uint16_t gdt_offset) -> void; - -} // namespace teachos::arch::kernel::cpu - -#endif // TEACHOS_ARCH_X86_64_KERNEL_CPU_TR_HPP diff --git a/arch/x86_64/pre/include/arch/kernel/halt.hpp b/arch/x86_64/pre/include/arch/kernel/halt.hpp deleted file mode 100644 index 377acc0..0000000 --- a/arch/x86_64/pre/include/arch/kernel/halt.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_KERNEL_HALT_HPP -#define TEACHOS_ARCH_X86_64_KERNEL_HALT_HPP - -namespace teachos::arch::kernel -{ - /** - * @brief Halts the kernel execution, meaning any code after a call to this will not run anymore. - */ - extern "C" [[noreturn]] auto halt() -> void; - -} // namespace teachos::arch::kernel - -#endif // TEACHOS_ARCH_X86_64_KERNEL_HALT_HPP diff --git a/arch/x86_64/pre/include/arch/kernel/main.hpp b/arch/x86_64/pre/include/arch/kernel/main.hpp deleted file mode 100644 index a13e5f4..0000000 --- a/arch/x86_64/pre/include/arch/kernel/main.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_KERNEL_MAIN_HPP -#define TEACHOS_ARCH_X86_64_KERNEL_MAIN_HPP - -namespace teachos::arch::kernel -{ - /** - * @brief Initalizes the kernel system. - */ - auto main() -> void; - -} // namespace teachos::arch::kernel - -#endif // TEACHOS_ARCH_X86_64_KERNEL_MAIN_HPP diff --git a/arch/x86_64/pre/include/arch/user/main.hpp b/arch/x86_64/pre/include/arch/user/main.hpp deleted file mode 100644 index c168a1f..0000000 --- a/arch/x86_64/pre/include/arch/user/main.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_USER_MAIN_HPP -#define TEACHOS_ARCH_X86_64_USER_MAIN_HPP - -namespace teachos::arch::user -{ - /** - * @brief User Main method. If this method finishes there is no code left to run and the whole OS will shut down. - * Additionally this main method is executed at Ring 3 and accessing CPU Registers or Kernel level functionality can - * only be done over syscalls and not directly anymore. - */ - [[gnu::section(".user_text")]] - auto main() -> void; - -} // namespace teachos::arch::user - -#endif // TEACHOS_ARCH_X86_64_USER_MAIN_HPP diff --git a/arch/x86_64/pre/src/context_switching/interrupt_descriptor_table/gate_descriptor.cpp b/arch/x86_64/pre/src/context_switching/interrupt_descriptor_table/gate_descriptor.cpp deleted file mode 100644 index 28f289c..0000000 --- a/arch/x86_64/pre/src/context_switching/interrupt_descriptor_table/gate_descriptor.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "arch/context_switching/interrupt_descriptor_table/gate_descriptor.hpp" - -namespace teachos::arch::context_switching::interrupt_descriptor_table -{ - gate_descriptor::gate_descriptor(uint128_t flags) - : _offset_1(flags) - , _selector(flags >> 19U, flags >> 16U) - , _ist(flags >> 32U) - , _flags(flags >> 40U) - , _offset_2(flags >> 48U) - { - // Nothing to do. - } - - gate_descriptor::gate_descriptor(segment_selector selector, ist_offset ist, idt_flags flags, uint64_t offset) - : _offset_1(offset) - , _selector(selector) - , _ist(ist) - , _flags(flags) - , _offset_2(offset >> 16U) - { - // Nothing to do. - } -} // namespace teachos::arch::context_switching::interrupt_descriptor_table diff --git a/arch/x86_64/pre/src/context_switching/interrupt_descriptor_table/idt_flags.cpp b/arch/x86_64/pre/src/context_switching/interrupt_descriptor_table/idt_flags.cpp deleted file mode 100644 index f3b9d5e..0000000 --- a/arch/x86_64/pre/src/context_switching/interrupt_descriptor_table/idt_flags.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "arch/context_switching/interrupt_descriptor_table/idt_flags.hpp" - -namespace teachos::arch::context_switching::interrupt_descriptor_table -{ - idt_flags::idt_flags(uint8_t flags) - : _flags(flags) - { - // Nothing to do. - } - - auto idt_flags::contains_flags(std::bitset<8U> other) const -> bool - { - return (std::bitset<8U>{_flags} & other) == other; - } - - auto idt_flags::operator|=(std::bitset<8U> other) -> void - { - _flags |= other.to_ulong(); - } -} // namespace teachos::arch::context_switching::interrupt_descriptor_table diff --git a/arch/x86_64/pre/src/context_switching/interrupt_descriptor_table/interrupt_descriptor_table.cpp b/arch/x86_64/pre/src/context_switching/interrupt_descriptor_table/interrupt_descriptor_table.cpp deleted file mode 100644 index 8640385..0000000 --- a/arch/x86_64/pre/src/context_switching/interrupt_descriptor_table/interrupt_descriptor_table.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "arch/context_switching/interrupt_descriptor_table/interrupt_descriptor_table.hpp" - -#include "arch/exception_handling/assert.hpp" -#include "arch/interrupt_handling/generic_interrupt_handler.hpp" -#include "arch/kernel/cpu/idtr.hpp" - -namespace teachos::arch::context_switching::interrupt_descriptor_table -{ - namespace - { - /// @brief Amount of currently reserved interrupt indicies. - /// See https://wiki.osdev.org/Interrupt_Descriptor_Table#IDT_items for more information. - constexpr uint16_t RESERVED_INTERRUPT_COUNT = 256U; - - auto create_interrupt_descriptor_table() -> interrupt_descriptor_table - { - interrupt_descriptor_table interrupt_descriptor_table{RESERVED_INTERRUPT_COUNT}; - - uint64_t offset = reinterpret_cast<uint64_t>(interrupt_handling::generic_interrupt_handler); - segment_selector selector{1U, segment_selector::REQUEST_LEVEL_KERNEL}; - ist_offset ist{0U}; - idt_flags flags{idt_flags::DESCRIPTOR_LEVEL_KERNEL | idt_flags::INTERRUPT_GATE | idt_flags::PRESENT}; - - for (std::size_t i = 0; i < interrupt_descriptor_table.size(); i++) - { - interrupt_descriptor_table.at(i) = {selector, ist, flags, offset}; - } - - return interrupt_descriptor_table; - } - } // namespace - - auto get_or_create_interrupt_descriptor_table() -> interrupt_descriptor_table & - { - // Interrupt Descriptor Table needs to be kept alive - interrupt_descriptor_table static idt = create_interrupt_descriptor_table(); - return idt; - } - - auto update_interrupt_descriptor_table_register() -> void - { - decltype(auto) idt = get_or_create_interrupt_descriptor_table(); - - interrupt_descriptor_table_pointer idt_pointer{static_cast<uint16_t>((idt.size() * sizeof(gate_descriptor)) - 1), - idt.data()}; - kernel::cpu::load_interrupt_descriptor_table(idt_pointer); - - auto const stored_gdt_pointer = kernel::cpu::store_interrupt_descriptor_table(); - arch::exception_handling::assert( - idt_pointer == stored_gdt_pointer, - "[Interrupt Descriptor Table] Loaded IDTR value is not the same as the stored value."); - } -} // namespace teachos::arch::context_switching::interrupt_descriptor_table diff --git a/arch/x86_64/pre/src/context_switching/interrupt_descriptor_table/interrupt_descriptor_table_pointer.cpp b/arch/x86_64/pre/src/context_switching/interrupt_descriptor_table/interrupt_descriptor_table_pointer.cpp deleted file mode 100644 index 7bcbae6..0000000 --- a/arch/x86_64/pre/src/context_switching/interrupt_descriptor_table/interrupt_descriptor_table_pointer.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "arch/context_switching/interrupt_descriptor_table/interrupt_descriptor_table_pointer.hpp" - -namespace teachos::arch::context_switching::interrupt_descriptor_table -{ - interrupt_descriptor_table_pointer::interrupt_descriptor_table_pointer(uint16_t table_length, - gate_descriptor * address) - : table_length(table_length) - , address(address) - { - // Nothing to do. - } - -} // namespace teachos::arch::context_switching::interrupt_descriptor_table diff --git a/arch/x86_64/pre/src/context_switching/interrupt_descriptor_table/ist_offset.cpp b/arch/x86_64/pre/src/context_switching/interrupt_descriptor_table/ist_offset.cpp deleted file mode 100644 index a70e75d..0000000 --- a/arch/x86_64/pre/src/context_switching/interrupt_descriptor_table/ist_offset.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "arch/context_switching/interrupt_descriptor_table/ist_offset.hpp" - -namespace teachos::arch::context_switching::interrupt_descriptor_table -{ - ist_offset::ist_offset(uint8_t index) - : _ist(index) - { - // Nothing to do. - } -} // namespace teachos::arch::context_switching::interrupt_descriptor_table diff --git a/arch/x86_64/pre/src/context_switching/interrupt_descriptor_table/segment_selector.cpp b/arch/x86_64/pre/src/context_switching/interrupt_descriptor_table/segment_selector.cpp deleted file mode 100644 index 25ba859..0000000 --- a/arch/x86_64/pre/src/context_switching/interrupt_descriptor_table/segment_selector.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "arch/context_switching/interrupt_descriptor_table/segment_selector.hpp" - -namespace teachos::arch::context_switching::interrupt_descriptor_table -{ - auto segment_selector::contains_flags(std::bitset<3U> other) const -> bool - { - return (std::bitset<3U>{_flags} & other) == other; - } - - auto segment_selector::get_index() const -> uint16_t - { - return _index; - } - - auto segment_selector::operator|=(std::bitset<3U> other) -> void - { - _flags |= other.to_ulong(); - } - - segment_selector::operator uint16_t() const - { - return *reinterpret_cast<uint16_t const *>(this); - } -} // namespace teachos::arch::context_switching::interrupt_descriptor_table diff --git a/arch/x86_64/pre/src/context_switching/main.cpp b/arch/x86_64/pre/src/context_switching/main.cpp deleted file mode 100644 index 3eb6dae..0000000 --- a/arch/x86_64/pre/src/context_switching/main.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "arch/context_switching/main.hpp" - -#include "arch/boot/pointers.hpp" -#include "arch/context_switching/syscall/syscall_enable.hpp" -#include "arch/kernel/cpu/call.hpp" -#include "arch/kernel/cpu/if.hpp" -#include "arch/kernel/cpu/segment_register.hpp" -#include "arch/kernel/cpu/tr.hpp" -#include "arch/user/main.hpp" - -namespace teachos::arch::context_switching -{ - namespace - { - constexpr interrupt_descriptor_table::segment_selector KERNEL_CODE_SEGMENT_SELECTOR{ - 1U, interrupt_descriptor_table::segment_selector::REQUEST_LEVEL_KERNEL}; - constexpr kernel::cpu::far_pointer KERNEL_CODE_POINTER{&kernel::cpu::reload_data_segment_registers, - KERNEL_CODE_SEGMENT_SELECTOR}; - constexpr context_switching::interrupt_descriptor_table::segment_selector USER_CODE_SEGMENT_SELECTOR{ - 3U, context_switching::interrupt_descriptor_table::segment_selector::REQUEST_LEVEL_USER}; - constexpr context_switching::interrupt_descriptor_table::segment_selector USER_DATA_SEGMENT_SELECTOR{ - 4U, context_switching::interrupt_descriptor_table::segment_selector::REQUEST_LEVEL_USER}; - - auto reload_gdtr() -> void - { - kernel::cpu::call(KERNEL_CODE_POINTER); - } - } // namespace - - auto initialize_descriptor_tables() -> descriptor_tables - { - bool static initalized = false; - - if (!initalized) - { - kernel::cpu::clear_interrupt_flag(); - - segment_descriptor_table::update_gdtr(); - interrupt_descriptor_table::update_interrupt_descriptor_table_register(); - - reload_gdtr(); - segment_descriptor_table::update_tss_register(); - - kernel::cpu::set_interrupt_flag(); - initalized = true; - } - - descriptor_tables tables = {segment_descriptor_table::get_or_create_gdt(), - interrupt_descriptor_table::get_or_create_interrupt_descriptor_table()}; - return tables; - } - - auto switch_to_user_mode() -> void - { - syscall::enable_syscall(); - switch_context(USER_DATA_SEGMENT_SELECTOR, USER_CODE_SEGMENT_SELECTOR, user::main); - } - - auto switch_context(interrupt_descriptor_table::segment_selector data_segment, - interrupt_descriptor_table::segment_selector code_segment, void (*return_function)()) -> void - { - (void)initialize_descriptor_tables(); - kernel::cpu::set_data_segment_registers(data_segment); - kernel::cpu::set_code_segment_register(data_segment, code_segment, reinterpret_cast<uint64_t>(return_function)); - } -} // namespace teachos::arch::context_switching diff --git a/arch/x86_64/pre/src/context_switching/syscall/main.cpp b/arch/x86_64/pre/src/context_switching/syscall/main.cpp deleted file mode 100644 index b4ab468..0000000 --- a/arch/x86_64/pre/src/context_switching/syscall/main.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "arch/context_switching/syscall/main.hpp" - -namespace teachos::arch::context_switching::syscall -{ - auto syscall(type syscall_number, arguments args) -> response - { - asm volatile("mov %[input], %%rax" - : /* no output from call */ - : [input] "m"(syscall_number) - : "memory"); - - asm volatile("mov %[input], %%rdi " : /* no output from call */ : [input] "m"(args.arg_0) : "memory"); - asm volatile("mov %[input], %%rsi" : /* no output from call */ : [input] "m"(args.arg_1) : "memory"); - asm volatile("mov %[input], %%rdx" : /* no output from call */ : [input] "m"(args.arg_2) : "memory"); - asm volatile("mov %[input], %%r10" : /* no output from call */ : [input] "m"(args.arg_3) : "memory"); - asm volatile("mov %[input], %%r8" : /* no output from call */ : [input] "m"(args.arg_4) : "memory"); - asm volatile("mov %[input], %%r9" : /* no output from call */ : [input] "m"(args.arg_5) : "memory"); - - asm volatile("syscall"); - - arguments values{}; - asm volatile("mov %%rdi, %[output]" : [output] "=m"(values.arg_0)); - asm volatile("mov %%rsi, %[output]" : [output] "=m"(values.arg_1)); - asm volatile("mov %%rdx, %[output]" : [output] "=m"(values.arg_2)); - asm volatile("mov %%r10, %[output]" : [output] "=m"(values.arg_3)); - asm volatile("mov %%r8, %[output]" : [output] "=m"(values.arg_4)); - asm volatile("mov %%r9, %[output]" : [output] "=m"(values.arg_5)); - - error error_code{}; - asm volatile("mov %%al, %[output]" : [output] "=m"(error_code)); - - return {error_code, values}; - } - -} // namespace teachos::arch::context_switching::syscall diff --git a/arch/x86_64/pre/src/context_switching/syscall/syscall_enable.cpp b/arch/x86_64/pre/src/context_switching/syscall/syscall_enable.cpp deleted file mode 100644 index dbb3ed9..0000000 --- a/arch/x86_64/pre/src/context_switching/syscall/syscall_enable.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "arch/context_switching/syscall/syscall_enable.hpp" - -#include "arch/context_switching/interrupt_descriptor_table/segment_selector.hpp" -#include "arch/context_switching/syscall/syscall_handler.hpp" -#include "arch/kernel/cpu/msr.hpp" - -namespace teachos::arch::context_switching::syscall -{ - namespace - { - constexpr interrupt_descriptor_table::segment_selector KERNEL_CODE_SEGMENT_SELECTOR{ - 1U, interrupt_descriptor_table::segment_selector::REQUEST_LEVEL_KERNEL}; - - constexpr auto IA32_STAR_ADDRESS = 0xC000'0081; - constexpr auto IA32_LSTAR_ADDRESS = 0xC000'0082; - constexpr auto IA32_FMASK_ADDRESS = 0xC000'0084; - - } // namespace - - auto enable_syscall() -> void - { - uint64_t const syscall_function = reinterpret_cast<uint64_t>(syscall_handler); - kernel::cpu::write_msr(IA32_LSTAR_ADDRESS, syscall_function); - kernel::cpu::write_msr(IA32_FMASK_ADDRESS, 0U); - - uint64_t const kernel_cs = KERNEL_CODE_SEGMENT_SELECTOR; - uint64_t const star_value = (kernel_cs << 32) | (kernel_cs << 48); - kernel::cpu::write_msr(IA32_STAR_ADDRESS, star_value); - - kernel::cpu::set_efer_bit(kernel::cpu::efer_flags::SCE); - } -} // namespace teachos::arch::context_switching::syscall diff --git a/arch/x86_64/pre/src/context_switching/syscall/syscall_handler.cpp b/arch/x86_64/pre/src/context_switching/syscall/syscall_handler.cpp deleted file mode 100644 index c120f77..0000000 --- a/arch/x86_64/pre/src/context_switching/syscall/syscall_handler.cpp +++ /dev/null @@ -1,121 +0,0 @@ -#include "arch/context_switching/syscall/syscall_handler.hpp" - -#include "arch/context_switching/syscall/main.hpp" -#include "arch/exception_handling/assert.hpp" -#include "arch/exception_handling/panic.hpp" -#include "arch/memory/heap/global_heap_allocator.hpp" -#include "arch/memory/main.hpp" -#include "arch/video/vga/text.hpp" - -namespace teachos::arch::context_switching::syscall -{ - - namespace - { - auto write_to_vga_buffer(uint64_t buffer) -> response - { - video::vga::text::write(reinterpret_cast<char const *>(buffer), - video::vga::text::common_attributes::green_on_black); - video::vga::text::newline(); - return {error::OK}; - } - - auto expand_user_heap() -> response - { - auto static current_heap_end = memory::heap::USER_HEAP_START; - uint64_t const heap_start = current_heap_end; - memory::remap_heap(heap_start, memory::heap::USER_HEAP_SIZE, memory::paging::entry::USER_ACCESSIBLE); - current_heap_end += memory::heap::USER_HEAP_SIZE; - return { - error::OK, - {heap_start, memory::heap::USER_HEAP_SIZE} - }; - } - } // namespace - - auto syscall_handler() -> void - { - // Saving state of rcx and r11 because it is required by sysretq to function. - // Calls to other functions potentially overwrite these registers, because of - // callee saved calling convention. - uint64_t return_instruction_pointer, rflags = {}; - asm volatile("mov %%rcx, %[output]" : [output] "=m"(return_instruction_pointer)); - asm volatile("mov %%r11, %[output]" : [output] "=m"(rflags)); - - uint64_t syscall_number, arg_0, arg_1, arg_2, arg_3, arg_4, arg_5 = {}; - asm volatile("mov %%rdi, %[output]" : [output] "=m"(arg_0)); - asm volatile("mov %%rsi, %[output]" : [output] "=m"(arg_1)); - asm volatile("mov %%rdx, %[output]" : [output] "=m"(arg_2)); - asm volatile("mov %%r10, %[output]" : [output] "=m"(arg_3)); - asm volatile("mov %%r8, %[output]" : [output] "=m"(arg_4)); - asm volatile("mov %%r9, %[output]" : [output] "=m"(arg_5)); - - // RAX is read last, because paired with our type enum, we can use it to check - // if the register has been written by the compiled code between executing the syscall - // and now. - asm volatile("mov %%rax, %[output]" : [output] "=m"(syscall_number)); - - response result; - switch (static_cast<type>(syscall_number)) - { - case type::WRITE: - result = write_to_vga_buffer(arg_0); - break; - case type::EXPAND_HEAP: - result = expand_user_heap(); - break; - case type::ASSERT: - teachos::arch::exception_handling::assert(arg_0, reinterpret_cast<char const *>(arg_1)); - break; - default: - teachos::arch::exception_handling::panic("[Syscall Handler] Invalid syscall number"); - break; - } - - asm volatile("mov %[input], %%rax" - : /* no output from call */ - : [input] "m"(result.error_code) - : "memory"); - - asm volatile("mov %[input], %%rdi" - : /* no output from call */ - : [input] "m"(result.values.arg_0) - : "memory"); - asm volatile("mov %[input], %%rsi" - : /* no output from call */ - : [input] "m"(result.values.arg_1) - : "memory"); - asm volatile("mov %[input], %%rdx" - : /* no output from call */ - : [input] "m"(result.values.arg_2) - : "memory"); - asm volatile("mov %[input], %%r10" - : /* no output from call */ - : [input] "m"(result.values.arg_3) - : "memory"); - asm volatile("mov %[input], %%r8" - : /* no output from call */ - : [input] "m"(result.values.arg_4) - : "memory"); - asm volatile("mov %[input], %%r9" - : /* no output from call */ - : [input] "m"(result.values.arg_5) - : "memory"); - - asm volatile("mov %[input], %%rcx" - : /* no output from call */ - : [input] "m"(return_instruction_pointer) - : "memory"); - asm volatile("mov %[input], %%r11" - : /* no output from call */ - : [input] "m"(rflags) - : "memory"); - - // Additionally call leave, because x86 allocates stack space for the internal variables. If we do not clean up this - // newly created stack frame the syscall instruction that landed in this syscall_handler, will never return to the - // method that originally called it, because the RIP has not been restored from the previous stack frame. - asm volatile("leave\n" - "sysretq"); - } - -} // namespace teachos::arch::context_switching::syscall diff --git a/arch/x86_64/pre/src/interrupt_handling/generic_interrupt_handler.cpp b/arch/x86_64/pre/src/interrupt_handling/generic_interrupt_handler.cpp deleted file mode 100644 index 9d061a8..0000000 --- a/arch/x86_64/pre/src/interrupt_handling/generic_interrupt_handler.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "arch/interrupt_handling/generic_interrupt_handler.hpp" - -#include "arch/video/vga/text.hpp" - -namespace teachos::arch::interrupt_handling -{ - auto generic_interrupt_handler(interrupt_frame * frame) -> void - { - (void)frame; - video::vga::text::write("An Interrupt occurred.", video::vga::text::common_attributes::green_on_black); - video::vga::text::newline(); - } -} // namespace teachos::arch::interrupt_handling diff --git a/arch/x86_64/pre/src/kernel/cpu/call.cpp b/arch/x86_64/pre/src/kernel/cpu/call.cpp deleted file mode 100644 index 98fa248..0000000 --- a/arch/x86_64/pre/src/kernel/cpu/call.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "arch/kernel/cpu/call.hpp" - -namespace teachos::arch::kernel::cpu -{ - auto call(far_pointer pointer) -> void - { - asm volatile("rex64 lcall *%[input]" : /* no output from call */ : [input] "m"(pointer)); - } -} // namespace teachos::arch::kernel::cpu diff --git a/arch/x86_64/pre/src/kernel/cpu/idtr.cpp b/arch/x86_64/pre/src/kernel/cpu/idtr.cpp deleted file mode 100644 index 7aa20c1..0000000 --- a/arch/x86_64/pre/src/kernel/cpu/idtr.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "arch/kernel/cpu/idtr.hpp" - -namespace teachos::arch::kernel::cpu -{ - auto store_interrupt_descriptor_table() - -> context_switching::interrupt_descriptor_table::interrupt_descriptor_table_pointer - { - context_switching::interrupt_descriptor_table::interrupt_descriptor_table_pointer current_value{}; - asm("sidt %[output]" : [output] "=m"(current_value)); - return current_value; - } - - auto load_interrupt_descriptor_table( - context_switching::interrupt_descriptor_table::interrupt_descriptor_table_pointer const & idt_pointer) -> void - { - asm volatile("lidt %[input]" : /* no output from call */ : [input] "m"(idt_pointer)); - } -} // namespace teachos::arch::kernel::cpu diff --git a/arch/x86_64/pre/src/kernel/cpu/if.cpp b/arch/x86_64/pre/src/kernel/cpu/if.cpp deleted file mode 100644 index 5d056fc..0000000 --- a/arch/x86_64/pre/src/kernel/cpu/if.cpp +++ /dev/null @@ -1,13 +0,0 @@ -namespace teachos::arch::kernel::cpu -{ - auto set_interrupt_flag() -> void - { - asm volatile("sti"); - } - - auto clear_interrupt_flag() -> void - { - asm volatile("cli"); - } - -} // namespace teachos::arch::kernel::cpu diff --git a/arch/x86_64/pre/src/kernel/cpu/tr.cpp b/arch/x86_64/pre/src/kernel/cpu/tr.cpp deleted file mode 100644 index a435540..0000000 --- a/arch/x86_64/pre/src/kernel/cpu/tr.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "arch/kernel/cpu/tr.hpp" - -namespace teachos::arch::kernel::cpu -{ - auto store_task_register() -> uint16_t - { - uint16_t current_value{}; - asm("str %[output]" : [output] "=r"(current_value)); - return current_value; - } - - auto load_task_register(uint16_t gdt_offset) -> void - { - asm volatile("ltr %[input]" : /* no output from call */ : [input] "m"(gdt_offset)); - } -} // namespace teachos::arch::kernel::cpu diff --git a/arch/x86_64/pre/src/kernel/main.cpp b/arch/x86_64/pre/src/kernel/main.cpp deleted file mode 100644 index 43b5f90..0000000 --- a/arch/x86_64/pre/src/kernel/main.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "arch/kernel/main.hpp" - -#include "arch/boot/pointers.hpp" -#include "arch/context_switching/interrupt_descriptor_table/segment_selector.hpp" -#include "arch/context_switching/main.hpp" -#include "arch/kernel/cpu/if.hpp" -#include "arch/kernel/cpu/segment_register.hpp" -#include "arch/memory/heap/bump_allocator.hpp" -#include "arch/memory/heap/global_heap_allocator.hpp" -#include "arch/memory/main.hpp" -#include "arch/memory/multiboot/reader.hpp" -#include "arch/stl/vector.hpp" -#include "arch/video/vga/text.hpp" - -namespace teachos::arch::kernel -{ - auto stack_overflow_test(int count) -> int - { - int test[5000] = {}; - if (test[0] == 0xFFFF) - { - return count; - } - count = stack_overflow_test(count); - return count++; - } - - auto heap_test() -> void - { - auto test2 = new memory::multiboot::memory_information{}; - auto test3 = new memory::multiboot::memory_information{}; - auto test4 = *test2; - auto test5 = *test3; - test4.kernel_end = 5000; - test5.kernel_end = 3000; - auto test6 = test4.kernel_end; - auto test7 = test5.kernel_end; - auto test8 = memory::multiboot::read_multiboot2(); - if (test6 && test7 && test8.kernel_end) - { - video::vga::text::write("Heap test successful", video::vga::text::common_attributes::green_on_black); - } - test2->kernel_end = 2000; - test2->kernel_start = 1000; - test2->multiboot_start = 2000; - delete test2; - delete test3; - - auto test9 = new int(50); - delete test9; - } - - auto main() -> void - { - video::vga::text::clear(); - video::vga::text::cursor(false); - video::vga::text::write("TeachOS is starting up...", video::vga::text::common_attributes::green_on_black); - video::vga::text::newline(); - - memory::initialize_memory_management(); - // stack_overflow_test(0); - - memory::heap::global_heap_allocator::register_heap_allocator(memory::heap::heap_allocator_type::LINKED_LIST); - // heap_test(); - - auto address = memory::heap::global_heap_allocator::kmalloc(8U); - (void)address; - - context_switching::switch_to_user_mode(); - } -} // namespace teachos::arch::kernel diff --git a/arch/x86_64/pre/src/user/main.cpp b/arch/x86_64/pre/src/user/main.cpp deleted file mode 100644 index 8b07e4a..0000000 --- a/arch/x86_64/pre/src/user/main.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "arch/user/main.hpp" - -#include "arch/context_switching/syscall/main.hpp" -#include "arch/memory/heap/global_heap_allocator.hpp" - -#include <algorithm> -#include <array> -#include <atomic> -#include <ranges> - -namespace teachos::arch::user -{ - auto main() -> void - { - constexpr char syscall_message[] = "Successfully entered user mode and wrote to VGA buffer via syscall!"; - context_switching::syscall::syscall(context_switching::syscall::type::WRITE, - {reinterpret_cast<uint64_t>(&syscall_message)}); - - // Test C++ standard library - std::array<std::atomic<uint8_t>, 4> array_test = {std::atomic<uint8_t>{5}, std::atomic<uint8_t>{10}, - std::atomic<uint8_t>{15}, std::atomic<uint8_t>{20}}; - std::ranges::for_each(array_test, [](auto & item) { - auto value = item.load(); - uint8_t max_value = std::max(value, uint8_t{10}); - item.exchange(max_value + 2); - }); - - auto address = new uint64_t{10U}; - (void)address; - - for (;;) - { - } - } -} // namespace teachos::arch::user |
