diff options
Diffstat (limited to 'arch/x86_64/include')
5 files changed, 40 insertions, 17 deletions
diff --git a/arch/x86_64/include/arch/context_switching/interrupt_descriptor_table/gate_descriptor.hpp b/arch/x86_64/include/arch/context_switching/interrupt_descriptor_table/gate_descriptor.hpp index e677cbb..22cd0f0 100644 --- a/arch/x86_64/include/arch/context_switching/interrupt_descriptor_table/gate_descriptor.hpp +++ b/arch/x86_64/include/arch/context_switching/interrupt_descriptor_table/gate_descriptor.hpp @@ -61,8 +61,7 @@ namespace teachos::arch::context_switching::interrupt_descriptor_table 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) - uint16_t _offset_2 = {}; ///< Middle 16 bits of handler function address (48 - 63) - uint32_t _offset_3 = {}; ///< Upper 32 bits of handler function address (for x86_64) (64 - 95) + 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 diff --git a/arch/x86_64/include/arch/context_switching/interrupt_descriptor_table/interrupt_descriptor_table.hpp b/arch/x86_64/include/arch/context_switching/interrupt_descriptor_table/interrupt_descriptor_table.hpp index e2ec4c5..b388e0e 100644 --- a/arch/x86_64/include/arch/context_switching/interrupt_descriptor_table/interrupt_descriptor_table.hpp +++ b/arch/x86_64/include/arch/context_switching/interrupt_descriptor_table/interrupt_descriptor_table.hpp @@ -6,12 +6,18 @@ namespace teachos::arch::context_switching::interrupt_descriptor_table { /** - * @brief Initializes the interrupt_descriptor_table by loading it - * in the IDTR register. + * @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 initialize_interrupt_descriptor_table() -> interrupt_descriptor_table &; + auto get_or_create_interrupt_descriptor_table() -> interrupt_descriptor_table &; } // namespace teachos::arch::context_switching::interrupt_descriptor_table diff --git a/arch/x86_64/include/arch/context_switching/segment_descriptor_table/gdt_flags.hpp b/arch/x86_64/include/arch/context_switching/segment_descriptor_table/gdt_flags.hpp index 8217bcb..d8c3cd1 100644 --- a/arch/x86_64/include/arch/context_switching/segment_descriptor_table/gdt_flags.hpp +++ b/arch/x86_64/include/arch/context_switching/segment_descriptor_table/gdt_flags.hpp @@ -18,17 +18,16 @@ namespace teachos::arch::context_switching::segment_descriptor_table */ enum bitset : uint8_t { - AVAILABLE = 1U << 0U, ///< Available for use by System software. For our purposes this is basically reserved. LONG_MODE = 1U << 1U, ///< Defines in IA-32e mode (64-bit code and 32-bit compatability mode) if the segment ///< contains 64-bit code. Otherwise this bit should always be 0. Enable if instructions ///< are executed in 64-bit code, otherwise they are executed in compatability 32-bit mode. - ///< If this is set the DEFAULT_OPERAND_SIZE/BIG bit needs to be clear (0). - - DEFAULT_OPERATION_SIZE = - 1U << 2U, ///< If clear, this is a 16-bit code segment; if set, this is a 32-bit segment. - BIG = 1U << 2U, ///< If set, the maximum offset size for a data segment is increased to 32-bit - ///< 0xffffffff. Otherwise it's the 16-bit max 0x0000ffff. Essentially the same meaning as "D". - + ///< If this bit is set the 3rd bit needs to be clear (0). + UPPER_BOUND = 1U << 2U, ///< Specifies the upper bound of the segment for expand down data segment. Enable for 4 + ///< GiB, 4 KiB otherwise. + STACK_POINTER_SIZE = 1U << 2U, ///< Specifies the size of the Stack Pointer (SP) for stack segments used for + ///< implicit stack operations. Enable for 32 bit, 16 bit otherwise. + DEFAULT_LENGTH = 1U << 2U, ///< Indicates the default length for code segments with effective addresses and + ///< operands. Enable for 32 bit, 16 bit otherwise. GRANULARITY = 1U << 3U, ///< Indicates the size the Limit value in the segment descriptor is scaled by 1 Byte ///< blocks if the bit is not set or by 4 KiB blocks if the bit is set. }; diff --git a/arch/x86_64/include/arch/context_switching/segment_descriptor_table/global_descriptor_table.hpp b/arch/x86_64/include/arch/context_switching/segment_descriptor_table/global_descriptor_table.hpp index f3067ba..bd69a46 100644 --- a/arch/x86_64/include/arch/context_switching/segment_descriptor_table/global_descriptor_table.hpp +++ b/arch/x86_64/include/arch/context_switching/segment_descriptor_table/global_descriptor_table.hpp @@ -7,12 +7,30 @@ namespace teachos::arch::context_switching::segment_descriptor_table { /** - * @brief Initializes the global_descriptor_table and task_state_segment by loading them - * in the GDTR and TR registers respectively. + * @brief Creates the global 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 global_descriptor_table. */ - auto initialize_global_descriptor_table() -> global_descriptor_table &; + auto get_or_create_global_descriptor_table() -> global_descriptor_table &; + + /** + * @brief Updates the GDTR with the created global descriptor table. If it has not been created yet this + * method will create it. + * + * @note This method will only set the GDTR, but for the processor to actually register the change a far jump + * has to be executed. This also has to be done before updating the TR. + */ + auto update_global_descriptor_table_register() -> void; + + /** + * @brief Updates the TR with the created task state segment. If it has not been created yet this + * method will create it. + * + * @note This method should only be called after update_global_descriptor_table_register() and a far jump has been + * executed. Because before that trying to access the segment will cause an exception. + */ + auto update_task_state_segment_register() -> void; } // namespace teachos::arch::context_switching::segment_descriptor_table diff --git a/arch/x86_64/include/arch/kernel/cpu/jmp.hpp b/arch/x86_64/include/arch/kernel/cpu/jmp.hpp index 0ed38e9..1657c18 100644 --- a/arch/x86_64/include/arch/kernel/cpu/jmp.hpp +++ b/arch/x86_64/include/arch/kernel/cpu/jmp.hpp @@ -13,7 +13,8 @@ namespace teachos::arch::kernel::cpu struct far_pointer { void (*function)(); ///< Address of the function we want to jump too. (0-63) - std::uint16_t index; ///< Index of the GDT entry we want to load into register CS. (64-79) + context_switching::interrupt_descriptor_table::segment_selector + selector; ///< Segment selector pointing to the GDT entry we want to load into register CS. (64-79) }; /** |
