diff --git a/repos/base-hw/lib/mk/spec/x86_64/core-hw.inc b/repos/base-hw/lib/mk/spec/x86_64/core-hw.inc index 3ed076393..4813f2df0 100644 --- a/repos/base-hw/lib/mk/spec/x86_64/core-hw.inc +++ b/repos/base-hw/lib/mk/spec/x86_64/core-hw.inc @@ -20,14 +20,12 @@ SRC_CC += spec/x86/io_port_session_support.cc SRC_CC += spec/x86_64/bios_data_area.cc SRC_CC += spec/x86_64/cpu.cc SRC_CC += spec/x86_64/fpu.cc -SRC_CC += spec/x86_64/idt.cc SRC_CC += spec/x86_64/kernel/cpu.cc SRC_CC += spec/x86_64/kernel/cpu_context.cc SRC_CC += spec/x86_64/kernel/pd.cc SRC_CC += spec/x86_64/kernel/thread.cc SRC_CC += spec/x86_64/kernel/thread.cc SRC_CC += spec/x86_64/platform_support_common.cc -SRC_CC += spec/x86_64/tss.cc NR_OF_CPUS = 1 diff --git a/repos/base-hw/src/core/include/spec/x86_64/cpu.h b/repos/base-hw/src/core/include/spec/x86_64/cpu.h index 711753fc7..e1490fe47 100644 --- a/repos/base-hw/src/core/include/spec/x86_64/cpu.h +++ b/repos/base-hw/src/core/include/spec/x86_64/cpu.h @@ -1,7 +1,10 @@ /* - * \brief CPU driver for core + * \brief x86_64 CPU driver for core + * \author Adrian-Ken Rueegsegger * \author Martin stein - * \date 2015-04-20 + * \author Reto Buerki + * \author Stefan Kalkowski + * \date 2015-02-06 */ /* @@ -14,9 +17,278 @@ #ifndef _CORE__INCLUDE__SPEC__X86_64__CPU_H_ #define _CORE__INCLUDE__SPEC__X86_64__CPU_H_ -/* core includes */ -#include +/* Genode includes */ +#include +#include +#include -namespace Genode { typedef __uint128_t sizet_arithm_t; } +/* base includes */ +#include + +/* core includes */ +#include +#include + +namespace Genode { + class Cpu; + using sizet_arithm_t = __uint128_t; +} + + +class Genode::Cpu +{ + public: + + struct Pd {}; + + struct Pseudo_descriptor; + + struct Cr0; /* Control register 0 */ + struct Cr2; /* Control register 2 */ + struct Cr3; /* Control register 3 */ + struct Cr4; /* Control register 4 */ + + + /** + * Task State Segment (TSS) + * + * See Intel SDM Vol. 3A, section 7.7 + */ + struct Tss { static void init(); }; + + + /** + * Interrupt Descriptor Table (IDT) + * + * See Intel SDM Vol. 3A, section 6.10 + */ + struct Idt { static void init(); }; + + + /** + * Global Descriptor Table (GDT) + * See Intel SDM Vol. 3A, section 3.5.1 + */ + struct Gdt { static void init(); }; + + + /** + * Extend basic CPU state by members relevant for 'base-hw' only + */ + struct Context : Cpu_state + { + /** + * Address of top-level paging structure. + */ + addr_t cr3; + + /** + * Return base of assigned translation table + */ + addr_t translation_table() const { return cr3; } + + /** + * Initialize context + * + * \param table physical base of appropriate translation table + * \param core whether it is a core thread or not + */ + void init(addr_t const table, bool core); + }; + + + /** + * An usermode execution state + */ + struct User_context : Context, Fpu::Context + { + /** + * Support for kernel calls + */ + void user_arg_0(Kernel::Call_arg const arg) { rdi = arg; } + void user_arg_1(Kernel::Call_arg const arg) { rsi = arg; } + void user_arg_2(Kernel::Call_arg const arg) { rdx = arg; } + void user_arg_3(Kernel::Call_arg const arg) { rcx = arg; } + void user_arg_4(Kernel::Call_arg const arg) { r8 = arg; } + void user_arg_5(Kernel::Call_arg const arg) { r9 = arg; } + void user_arg_6(Kernel::Call_arg const arg) { r10 = arg; } + void user_arg_7(Kernel::Call_arg const arg) { r11 = arg; } + Kernel::Call_arg user_arg_0() const { return rdi; } + Kernel::Call_arg user_arg_1() const { return rsi; } + Kernel::Call_arg user_arg_2() const { return rdx; } + Kernel::Call_arg user_arg_3() const { return rcx; } + Kernel::Call_arg user_arg_4() const { return r8; } + Kernel::Call_arg user_arg_5() const { return r9; } + Kernel::Call_arg user_arg_6() const { return r10; } + Kernel::Call_arg user_arg_7() const { return r11; } + }; + + protected: + + Fpu _fpu; + + public: + + Fpu & fpu() { return _fpu; } + + static constexpr addr_t exception_entry = 0xffff0000; + static constexpr addr_t mtc_size = 1 << 13; + + static addr_t virt_mtc_addr(addr_t virt_base, addr_t label); + + /** + * Wait for the next interrupt as cheap as possible + */ + static void wait_for_interrupt() { asm volatile ("pause"); } + + /** + * Return wether to retry an undefined user instruction after this call + */ + bool retry_undefined_instr(Context&) { return false; } + + + /** + * Return kernel name of the executing CPU + */ + static unsigned executing_id() { return 0; } + + /** + * Return kernel name of the primary CPU + */ + static unsigned primary_id() { return 0; } + + /** + * Switch to new context + * + * \param context next CPU context + */ + void switch_to(User_context &context) { _fpu.switch_to(context); } +}; + + +/** + * Pseudo Descriptor + * + * See Intel SDM Vol. 3A, section 3.5.1 + */ +struct Genode::Cpu::Pseudo_descriptor +{ + uint16_t const limit = 0; + uint64_t const base = 0; + + constexpr Pseudo_descriptor(uint16_t l, uint64_t b) : limit(l), base(b) {} +} __attribute__((packed)); + + +struct Genode::Cpu::Cr0 : Register<64> +{ + struct Pe : Bitfield< 0, 1> { }; /* Protection Enable */ + struct Mp : Bitfield< 1, 1> { }; /* Monitor Coprocessor */ + struct Em : Bitfield< 2, 1> { }; /* Emulation */ + struct Ts : Bitfield< 3, 1> { }; /* Task Switched */ + struct Et : Bitfield< 4, 1> { }; /* Extension Type */ + struct Ne : Bitfield< 5, 1> { }; /* Numeric Error */ + struct Wp : Bitfield<16, 1> { }; /* Write Protect */ + struct Am : Bitfield<18, 1> { }; /* Alignment Mask */ + struct Nw : Bitfield<29, 1> { }; /* Not Write-through */ + struct Cd : Bitfield<30, 1> { }; /* Cache Disable */ + struct Pg : Bitfield<31, 1> { }; /* Paging */ + + static void write(access_t const v) { + asm volatile ("mov %0, %%cr0" :: "r" (v) : ); } + + static access_t read() + { + access_t v; + asm volatile ("mov %%cr0, %0" : "=r" (v) :: ); + return v; + } +}; + + +/** + * Control register 2: Page-fault linear address + * + * See Intel SDM Vol. 3A, section 2.5. + */ +struct Genode::Cpu::Cr2 : Register<64> +{ + struct Addr : Bitfield<0, 63> { }; + + static access_t read() + { + access_t v; + asm volatile ("mov %%cr2, %0" : "=r" (v) :: ); + return v; + } +}; + + +/** + * Control register 3: Page-Directory base register + * + * See Intel SDM Vol. 3A, section 2.5. + */ +struct Genode::Cpu::Cr3 : Register<64> +{ + struct Pwt : Bitfield<3,1> { }; /* Page-level write-through */ + struct Pcd : Bitfield<4,1> { }; /* Page-level cache disable */ + struct Pdb : Bitfield<12, 36> { }; /* Page-directory base address */ + + static void write(access_t const v) { + asm volatile ("mov %0, %%cr3" :: "r" (v) : ); } + + static access_t read() + { + access_t v; + asm volatile ("mov %%cr3, %0" : "=r" (v) :: ); + return v; + } + + /** + * Return initialized value + * + * \param table base of targeted translation table + */ + static access_t init(addr_t const table) { + return Pdb::masked(table); } +}; + + +struct Genode::Cpu::Cr4 : Register<64> +{ + struct Vme : Bitfield< 0, 1> { }; /* Virtual-8086 Mode Extensions */ + struct Pvi : Bitfield< 1, 1> { }; /* Protected-Mode Virtual IRQs */ + struct Tsd : Bitfield< 2, 1> { }; /* Time Stamp Disable */ + struct De : Bitfield< 3, 1> { }; /* Debugging Exceptions */ + struct Pse : Bitfield< 4, 1> { }; /* Page Size Extensions */ + struct Pae : Bitfield< 5, 1> { }; /* Physical Address Extension */ + struct Mce : Bitfield< 6, 1> { }; /* Machine-Check Enable */ + struct Pge : Bitfield< 7, 1> { }; /* Page Global Enable */ + struct Pce : Bitfield< 8, 1> { }; /* Performance-Monitoring Counter + Enable*/ + struct Osfxsr : Bitfield< 9, 1> { }; /* OS Support for FXSAVE and + FXRSTOR instructions*/ + struct Osxmmexcpt : Bitfield<10, 1> { }; /* OS Support for Unmasked + SIMD/FPU Exceptions */ + struct Vmxe : Bitfield<13, 1> { }; /* VMX Enable */ + struct Smxe : Bitfield<14, 1> { }; /* SMX Enable */ + struct Fsgsbase : Bitfield<16, 1> { }; /* FSGSBASE-Enable */ + struct Pcide : Bitfield<17, 1> { }; /* PCIDE Enable */ + struct Osxsave : Bitfield<18, 1> { }; /* XSAVE and Processor Extended + States-Enable */ + struct Smep : Bitfield<20, 1> { }; /* SMEP Enable */ + struct Smap : Bitfield<21, 1> { }; /* SMAP Enable */ + + static void write(access_t const v) { + asm volatile ("mov %0, %%cr4" :: "r" (v) : ); } + + static access_t read() + { + access_t v; + asm volatile ("mov %%cr4, %0" : "=r" (v) :: ); + return v; + } +}; #endif /* _CORE__INCLUDE__SPEC__X86_64__CPU_H_ */ diff --git a/repos/base-hw/src/core/include/spec/x86_64/cpu_support.h b/repos/base-hw/src/core/include/spec/x86_64/cpu_support.h deleted file mode 100644 index 0ed55a81a..000000000 --- a/repos/base-hw/src/core/include/spec/x86_64/cpu_support.h +++ /dev/null @@ -1,258 +0,0 @@ -/* - * \brief x86_64 CPU driver for core - * \author Adrian-Ken Rueegsegger - * \author Martin stein - * \author Reto Buerki - * \date 2015-02-06 - */ - -/* - * Copyright (C) 2015 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _CORE__INCLUDE__SPEC__X86_64__CPU_SUPPORT_H_ -#define _CORE__INCLUDE__SPEC__X86_64__CPU_SUPPORT_H_ - -/* Genode includes */ -#include -#include -#include - -/* base includes */ -#include - -/* core includes */ -#include -#include -#include -#include -#include - -extern int _mt_idt; -extern int _mt_tss; - -namespace Genode { class Cpu; } - - -class Genode::Cpu -{ - public: - - struct Pd {}; - - struct Cr0; /* Control register 0 */ - struct Cr2; /* Control register 2 */ - struct Cr3; /* Control register 3 */ - struct Cr4; /* Control register 4 */ - - /** - * Extend basic CPU state by members relevant for 'base-hw' only - */ - struct Context : Cpu_state - { - /** - * Address of top-level paging structure. - */ - addr_t cr3; - - /** - * Return base of assigned translation table - */ - addr_t translation_table() const { return cr3; } - - /** - * Initialize context - * - * \param table physical base of appropriate translation table - * \param core whether it is a core thread or not - */ - void init(addr_t const table, bool core); - }; - - - /** - * An usermode execution state - */ - struct User_context : Context, Fpu::Context - { - /** - * Support for kernel calls - */ - void user_arg_0(Kernel::Call_arg const arg) { rdi = arg; } - void user_arg_1(Kernel::Call_arg const arg) { rsi = arg; } - void user_arg_2(Kernel::Call_arg const arg) { rdx = arg; } - void user_arg_3(Kernel::Call_arg const arg) { rcx = arg; } - void user_arg_4(Kernel::Call_arg const arg) { r8 = arg; } - void user_arg_5(Kernel::Call_arg const arg) { r9 = arg; } - void user_arg_6(Kernel::Call_arg const arg) { r10 = arg; } - void user_arg_7(Kernel::Call_arg const arg) { r11 = arg; } - Kernel::Call_arg user_arg_0() const { return rdi; } - Kernel::Call_arg user_arg_1() const { return rsi; } - Kernel::Call_arg user_arg_2() const { return rdx; } - Kernel::Call_arg user_arg_3() const { return rcx; } - Kernel::Call_arg user_arg_4() const { return r8; } - Kernel::Call_arg user_arg_5() const { return r9; } - Kernel::Call_arg user_arg_6() const { return r10; } - Kernel::Call_arg user_arg_7() const { return r11; } - }; - - protected: - - Fpu _fpu; - Idt * _idt; - Tss * _tss; - - public: - - Cpu(); - - Fpu & fpu() { return _fpu; } - - static constexpr addr_t exception_entry = 0xffff0000; - static constexpr addr_t mtc_size = 1 << 13; - - /** - * Wait for the next interrupt as cheap as possible - */ - static void wait_for_interrupt() { asm volatile ("pause"); } - - /** - * Return wether to retry an undefined user instruction after this call - */ - bool retry_undefined_instr(Context&) { return false; } - - - /** - * Return kernel name of the executing CPU - */ - static unsigned executing_id() { return 0; } - - /** - * Return kernel name of the primary CPU - */ - static unsigned primary_id() { return 0; } - - /** - * Switch to new context - * - * \param context next CPU context - */ - void switch_to(User_context &context) { _fpu.switch_to(context); } -}; - - -struct Genode::Cpu::Cr0 : Register<64> -{ - struct Pe : Bitfield< 0, 1> { }; /* Protection Enable */ - struct Mp : Bitfield< 1, 1> { }; /* Monitor Coprocessor */ - struct Em : Bitfield< 2, 1> { }; /* Emulation */ - struct Ts : Bitfield< 3, 1> { }; /* Task Switched */ - struct Et : Bitfield< 4, 1> { }; /* Extension Type */ - struct Ne : Bitfield< 5, 1> { }; /* Numeric Error */ - struct Wp : Bitfield<16, 1> { }; /* Write Protect */ - struct Am : Bitfield<18, 1> { }; /* Alignment Mask */ - struct Nw : Bitfield<29, 1> { }; /* Not Write-through */ - struct Cd : Bitfield<30, 1> { }; /* Cache Disable */ - struct Pg : Bitfield<31, 1> { }; /* Paging */ - - static void write(access_t const v) { - asm volatile ("mov %0, %%cr0" :: "r" (v) : ); } - - static access_t read() - { - access_t v; - asm volatile ("mov %%cr0, %0" : "=r" (v) :: ); - return v; - } -}; - - -/** - * Control register 2: Page-fault linear address - * - * See Intel SDM Vol. 3A, section 2.5. - */ -struct Genode::Cpu::Cr2 : Register<64> -{ - struct Addr : Bitfield<0, 63> { }; - - static access_t read() - { - access_t v; - asm volatile ("mov %%cr2, %0" : "=r" (v) :: ); - return v; - } -}; - - -/** - * Control register 3: Page-Directory base register - * - * See Intel SDM Vol. 3A, section 2.5. - */ -struct Genode::Cpu::Cr3 : Register<64> -{ - struct Pwt : Bitfield<3,1> { }; /* Page-level write-through */ - struct Pcd : Bitfield<4,1> { }; /* Page-level cache disable */ - struct Pdb : Bitfield<12, 36> { }; /* Page-directory base address */ - - static void write(access_t const v) { - asm volatile ("mov %0, %%cr3" :: "r" (v) : ); } - - static access_t read() - { - access_t v; - asm volatile ("mov %%cr3, %0" : "=r" (v) :: ); - return v; - } - - /** - * Return initialized value - * - * \param table base of targeted translation table - */ - static access_t init(addr_t const table) { - return Pdb::masked(table); } -}; - - -struct Genode::Cpu::Cr4 : Register<64> -{ - struct Vme : Bitfield< 0, 1> { }; /* Virtual-8086 Mode Extensions */ - struct Pvi : Bitfield< 1, 1> { }; /* Protected-Mode Virtual IRQs */ - struct Tsd : Bitfield< 2, 1> { }; /* Time Stamp Disable */ - struct De : Bitfield< 3, 1> { }; /* Debugging Exceptions */ - struct Pse : Bitfield< 4, 1> { }; /* Page Size Extensions */ - struct Pae : Bitfield< 5, 1> { }; /* Physical Address Extension */ - struct Mce : Bitfield< 6, 1> { }; /* Machine-Check Enable */ - struct Pge : Bitfield< 7, 1> { }; /* Page Global Enable */ - struct Pce : Bitfield< 8, 1> { }; /* Performance-Monitoring Counter - Enable*/ - struct Osfxsr : Bitfield< 9, 1> { }; /* OS Support for FXSAVE and - FXRSTOR instructions*/ - struct Osxmmexcpt : Bitfield<10, 1> { }; /* OS Support for Unmasked - SIMD/FPU Exceptions */ - struct Vmxe : Bitfield<13, 1> { }; /* VMX Enable */ - struct Smxe : Bitfield<14, 1> { }; /* SMX Enable */ - struct Fsgsbase : Bitfield<16, 1> { }; /* FSGSBASE-Enable */ - struct Pcide : Bitfield<17, 1> { }; /* PCIDE Enable */ - struct Osxsave : Bitfield<18, 1> { }; /* XSAVE and Processor Extended - States-Enable */ - struct Smep : Bitfield<20, 1> { }; /* SMEP Enable */ - struct Smap : Bitfield<21, 1> { }; /* SMAP Enable */ - - static void write(access_t const v) { - asm volatile ("mov %0, %%cr4" :: "r" (v) : ); } - - static access_t read() - { - access_t v; - asm volatile ("mov %%cr4, %0" : "=r" (v) :: ); - return v; - } -}; - -#endif /* _CORE__INCLUDE__SPEC__X86_64__CPU_SUPPORT_H_ */ diff --git a/repos/base-hw/src/core/include/spec/x86_64/gdt.h b/repos/base-hw/src/core/include/spec/x86_64/gdt.h deleted file mode 100644 index 5b3278feb..000000000 --- a/repos/base-hw/src/core/include/spec/x86_64/gdt.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * \brief Global Descriptor Table (GDT) - * \author Reto Buerki - * \date 2015-02-27 - */ - -/* - * Copyright (C) 2015 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _CORE__INCLUDE__SPEC__X86_64__GDT_H_ -#define _CORE__INCLUDE__SPEC__X86_64__GDT_H_ - -/* core includes */ -#include -#include - -extern int _mt_gdt_start; -extern int _mt_gdt_end; - -namespace Genode -{ - /** - * Global Descriptor Table (GDT) - * See Intel SDM Vol. 3A, section 3.5.1 - */ - class Gdt; -} - -class Genode::Gdt -{ - public: - - /** - * Load GDT from mtc region into GDTR. - * - * \param virt_base virtual base address of mode transition pages - */ - static void load(addr_t const virt_base) - { - addr_t const start = (addr_t)&_mt_gdt_start; - uint16_t const limit = _mt_gdt_end - _mt_gdt_start - 1; - uint64_t const base = _virt_mtc_addr(virt_base, start); - asm volatile ("lgdt %0" :: "m" (Pseudo_descriptor(limit, base))); - } -}; - -#endif /* _CORE__INCLUDE__SPEC__X86_64__GDT_H_ */ diff --git a/repos/base-hw/src/core/include/spec/x86_64/idt.h b/repos/base-hw/src/core/include/spec/x86_64/idt.h deleted file mode 100644 index da1358498..000000000 --- a/repos/base-hw/src/core/include/spec/x86_64/idt.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * \brief Interrupt Descriptor Table (IDT) - * \author Adrian-Ken Rueegsegger - * \author Reto Buerki - * \date 2015-02-13 - */ - -/* - * Copyright (C) 2015 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _CORE__INCLUDE__SPEC__X86_64__IDT_H_ -#define _CORE__INCLUDE__SPEC__X86_64__IDT_H_ - -#include - -namespace Genode -{ - /** - * Interrupt Descriptor Table (IDT) - * See Intel SDM Vol. 3A, section 6.10 - */ - class Idt; -} - -class Genode::Idt -{ - private: - - enum { - SIZE_IDT = 256, - SYSCALL_VEC = 0x80, - }; - - /** - * 64-Bit Mode IDT gate, see Intel SDM Vol. 3A, section 6.14.1. - */ - struct gate - { - uint16_t offset_15_00; - uint16_t segment_sel; - uint16_t flags; - uint16_t offset_31_16; - uint32_t offset_63_32; - uint32_t reserved; - }; - - /** - * IDT table - */ - __attribute__((aligned(8))) gate _table[SIZE_IDT]; - - public: - - /** - * Setup IDT. - * - * \param virt_base virtual base address of mode transition pages - */ - void setup(addr_t const virt_base); - - /** - * Load IDT into IDTR. - * - * \param virt_base virtual base address of mode transition pages - */ - void load(addr_t const virt_base); -}; - -#endif /* _CORE__INCLUDE__SPEC__X86_64__IDT_H_ */ diff --git a/repos/base-hw/src/core/include/spec/x86_64/mtc_util.h b/repos/base-hw/src/core/include/spec/x86_64/mtc_util.h deleted file mode 100644 index 7303fd7eb..000000000 --- a/repos/base-hw/src/core/include/spec/x86_64/mtc_util.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * \brief x86 utility functions - * \author Reto Buerki - * \date 2015-02-27 - */ - -/* - * Copyright (C) 2015 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _CORE__INCLUDE__SPEC__X86_64__MTC_UTIL_H_ -#define _CORE__INCLUDE__SPEC__X86_64__MTC_UTIL_H_ - -#include - -extern int _mt_begin; - -namespace Genode -{ - /** - * Return virtual mtc address of the given label for the specified - * virtual mode transition base. - * - * \param virt_base virtual base of the mode transition pages - */ - static addr_t _virt_mtc_addr(addr_t const virt_base, addr_t const label) - { - addr_t const phys_base = (addr_t)&_mt_begin; - return virt_base + (label - phys_base); - } -} - -#endif /* _CORE__INCLUDE__SPEC__X86_64__MTC_UTIL_H_ */ diff --git a/repos/base-hw/src/core/include/spec/x86_64/pseudo_descriptor.h b/repos/base-hw/src/core/include/spec/x86_64/pseudo_descriptor.h deleted file mode 100644 index 17ac2da47..000000000 --- a/repos/base-hw/src/core/include/spec/x86_64/pseudo_descriptor.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * \brief Pseudo Descriptor class - * \author Reto Buerki - * \date 2015-02-27 - */ - -/* - * Copyright (C) 2015 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _CORE__INCLUDE__SPEC__X86_64__PSEUDO_DESCRIPTOR_H_ -#define _CORE__INCLUDE__SPEC__X86_64__PSEUDO_DESCRIPTOR_H_ - -#include - -namespace Genode -{ - /** - * Pseudo Descriptor - * - * See Intel SDM Vol. 3A, section 3.5.1 - */ - class Pseudo_descriptor; -} - -class Genode::Pseudo_descriptor -{ - private: - uint16_t _limit; - uint64_t _base; - - public: - Pseudo_descriptor(uint16_t l, uint64_t b) : _limit(l), _base (b) { }; -} __attribute__((packed)); - -#endif /* _CORE__INCLUDE__SPEC__X86_64__PSEUDO_DESCRIPTOR_H_ */ diff --git a/repos/base-hw/src/core/include/spec/x86_64/tss.h b/repos/base-hw/src/core/include/spec/x86_64/tss.h deleted file mode 100644 index 0f2f92f26..000000000 --- a/repos/base-hw/src/core/include/spec/x86_64/tss.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * \brief 64-bit Task State Segment (TSS) - * \author Adrian-Ken Rueegsegger - * \author Reto Buerki - * \date 2015-02-21 - */ - -/* - * Copyright (C) 2015 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _CORE__INCLUDE__SPEC__X86_64__TSS_H_ -#define _CORE__INCLUDE__SPEC__X86_64__TSS_H_ - -#include - -namespace Genode -{ - /** - * Task State Segment (TSS) - * - * See Intel SDM Vol. 3A, section 7.7 - */ - class Tss; -} - -class Genode::Tss -{ - private: - - enum { - TSS_SELECTOR = 0x28, - }; - - uint32_t : 32; - addr_t rsp0; - addr_t rsp1; - addr_t rsp2; - uint64_t : 64; - addr_t ist[7]; - uint64_t : 64; - uint16_t : 16; - uint16_t iomap_base; - - public: - - /** - * Setup TSS. - * - * \param virt_base virtual base address of mode transition pages - */ - void setup(addr_t const virt_base); - - /** - * Load TSS into TR. - */ - void load(); - -}__attribute__((packed)); - -#endif /* _CORE__INCLUDE__SPEC__X86_64__TSS_H_ */ diff --git a/repos/base-hw/src/core/spec/x86_64/cpu.cc b/repos/base-hw/src/core/spec/x86_64/cpu.cc index 6e8362825..ddba61b20 100644 --- a/repos/base-hw/src/core/spec/x86_64/cpu.cc +++ b/repos/base-hw/src/core/spec/x86_64/cpu.cc @@ -15,18 +15,16 @@ #include #include -Genode::Cpu::Cpu() -{ - if (primary_id() == executing_id()) { - _idt = new (&_mt_idt) Idt(); - _idt->setup(Cpu::exception_entry); +extern int _mt_begin; +extern int _mt_tss; +extern int _mt_idt; +extern int _mt_gdt_start; +extern int _mt_gdt_end; - _tss = new (&_mt_tss) Tss(); - _tss->load(); - } - _idt->load(Cpu::exception_entry); - _tss->setup(Cpu::exception_entry); -} + +Genode::addr_t Genode::Cpu::virt_mtc_addr(Genode::addr_t virt_base, + Genode::addr_t label) { + return virt_base + (label - (addr_t)&_mt_begin); } void Genode::Cpu::Context::init(addr_t const table, bool core) @@ -45,5 +43,30 @@ void Genode::Cpu::Context::init(addr_t const table, bool core) */ eflags = EFLAGS_IF_SET; if (core) eflags |= EFLAGS_IOPL_3; - else Gdt::load(Cpu::exception_entry); + else Gdt::init(); +} + + +void Genode::Cpu::Tss::init() +{ + enum { TSS_SELECTOR = 0x28, }; + asm volatile ("ltr %w0" : : "r" (TSS_SELECTOR)); +} + + +void Genode::Cpu::Idt::init() +{ + Pseudo_descriptor descriptor { + (uint16_t)((addr_t)&_mt_tss - (addr_t)&_mt_idt), + (uint64_t)(virt_mtc_addr(exception_entry, (addr_t)&_mt_idt)) }; + asm volatile ("lidt %0" : : "m" (descriptor)); +} + + +void Genode::Cpu::Gdt::init() +{ + addr_t const start = (addr_t)&_mt_gdt_start; + uint16_t const limit = _mt_gdt_end - _mt_gdt_start - 1; + uint64_t const base = virt_mtc_addr(exception_entry, start); + asm volatile ("lgdt %0" :: "m" (Pseudo_descriptor(limit, base))); } diff --git a/repos/base-hw/src/core/spec/x86_64/idt.cc b/repos/base-hw/src/core/spec/x86_64/idt.cc deleted file mode 100644 index beb22f463..000000000 --- a/repos/base-hw/src/core/spec/x86_64/idt.cc +++ /dev/null @@ -1,52 +0,0 @@ -/* - * \brief Interrupt Descriptor Table (IDT) - * \author Adrian-Ken Rueegsegger - * \author Reto Buerki - * \date 2015-02-13 - */ - -/* - * Copyright (C) 2015 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -/* core includes */ -#include -#include -#include - -extern int _mt_idt; -extern int _mt_isrs; - -using namespace Genode; - - -void Idt::setup(addr_t const virt_base) -{ - addr_t base = _virt_mtc_addr(virt_base, (addr_t)&_mt_isrs); - addr_t isr_addr; - - for (unsigned vec = 0; vec < SIZE_IDT; vec++) { - /* ISRs are padded to 4 bytes */ - isr_addr = base + vec * 0xc; - - _table[vec].offset_15_00 = isr_addr & 0xffff; - _table[vec].segment_sel = 8; - _table[vec].flags = 0x8e00; - _table[vec].offset_31_16 = (isr_addr >> 16); - _table[vec].offset_63_32 = (isr_addr >> 32); - } - - /* Set DPL of syscall entry to 3 */ - _table[SYSCALL_VEC].flags = _table[SYSCALL_VEC].flags | 0x6000; -} - - -void Idt::load(addr_t const virt_base) -{ - uint16_t const limit = sizeof(_table) - 1; - uint64_t const base = _virt_mtc_addr(virt_base, (addr_t)&_mt_idt); - asm volatile ("lidt %0" : : "m" (Pseudo_descriptor(limit, base))); -} diff --git a/repos/base-hw/src/core/spec/x86_64/kernel/cpu.cc b/repos/base-hw/src/core/spec/x86_64/kernel/cpu.cc index 9feaba734..e7432180f 100644 --- a/repos/base-hw/src/core/spec/x86_64/kernel/cpu.cc +++ b/repos/base-hw/src/core/spec/x86_64/kernel/cpu.cc @@ -34,6 +34,9 @@ Cpu_idle::Cpu_idle(Cpu * const cpu) : Cpu_job(Cpu_priority::MIN, 0) void Kernel::Cpu::init(Pic &pic, Kernel::Pd &core_pd, Genode::Board&) { + Idt::init(); + Tss::init(); + Timer::disable_pit(); fpu().init(); diff --git a/repos/base-hw/src/core/spec/x86_64/mode_transition.s b/repos/base-hw/src/core/spec/x86_64/mode_transition.s index 330322421..dc1d8e6a7 100644 --- a/repos/base-hw/src/core/spec/x86_64/mode_transition.s +++ b/repos/base-hw/src/core/spec/x86_64/mode_transition.s @@ -37,9 +37,15 @@ /* mtc virt addresses */ .set MT_BASE, 0xffff0000 -.set MT_BUFFER, MT_BASE + (_mt_buffer - _mt_begin) -.set MT_MASTER, MT_BASE + (_mt_master_context_begin - _mt_begin) -.set MT_TSS, MT_BASE + (_mt_tss - _mt_begin) +.set MT_BUFFER, MT_BASE + (_mt_buffer - _mt_begin) +.set MT_MASTER, MT_BASE + (_mt_master_context_begin - _mt_begin) +.set MT_TSS, MT_BASE + (_mt_tss - _mt_begin) +.set MT_ISR, MT_BASE +.set MT_IRQ_STACK, MT_BASE + (_mt_kernel_interrupt_stack - _mt_begin) +.set MT_ISR_ENTRY_SIZE, 12 + +.set IDT_FLAGS_PRIVILEGED, 0x8e00 +.set IDT_FLAGS_UNPRIVILEGED, 0xee00 .macro _isr_entry .align 4, 0x90 @@ -60,6 +66,15 @@ jmp _mt_kernel_entry_pic .endm +.macro _idt_entry addr flags + .word \addr & 0xffff + .word 0x0008 + .word \flags + .word \addr >> 16 + .long \addr >> 32 + .long 0 +.endm + .section .text /* @@ -79,8 +94,6 @@ * On user exceptions the CPU has to jump to one of the following * Interrupt Service Routines (ISRs) to switch to a kernel context. */ - .global _mt_isrs - _mt_isrs: _exception 0 _exception 1 _exception 2 @@ -254,25 +267,45 @@ mov $1, %rax vmcall - /************************************************ - ** Space for Interrupt Descriptor Table (IDT) ** - ** See Intel SDM Vol. 3A, section 6.10 ** - ************************************************/ + /***************************************** + ** Interrupt Descriptor Table (IDT) ** + ** See Intel SDM Vol. 3A, section 6.10 ** + *****************************************/ .global _mt_idt .align 8 _mt_idt: - .space 1 << MIN_PAGE_SIZE_LOG2 - /*********************************************** - ** Space for 64-bit Task State Segment (TSS) ** - ** See Intel SDM Vol. 3A, section 7.7 ** - ***********************************************/ + /* first 128 entries */ + .set isr_addr, MT_ISR + .rept 0x80 + _idt_entry isr_addr IDT_FLAGS_PRIVILEGED + .set isr_addr, isr_addr + MT_ISR_ENTRY_SIZE + .endr + + /* syscall entry 0x80 */ + _idt_entry isr_addr IDT_FLAGS_UNPRIVILEGED + .set isr_addr, isr_addr + MT_ISR_ENTRY_SIZE + + /* remaing entries */ + .rept 127 + _idt_entry isr_addr IDT_FLAGS_PRIVILEGED + .set isr_addr, isr_addr + MT_ISR_ENTRY_SIZE + .endr + + /**************************************** + ** Task State Segment (TSS) ** + ** See Intel SDM Vol. 3A, section 7.7 ** + ****************************************/ .global _mt_tss .align 8 _mt_tss: - .space 104 + .space 4 + .quad MT_IRQ_STACK + .quad MT_IRQ_STACK + .quad MT_IRQ_STACK + .space 76 /****************************************** ** Global Descriptor Table (GDT) ** diff --git a/repos/base-hw/src/core/spec/x86_64/tss.cc b/repos/base-hw/src/core/spec/x86_64/tss.cc deleted file mode 100644 index 8bbf988d0..000000000 --- a/repos/base-hw/src/core/spec/x86_64/tss.cc +++ /dev/null @@ -1,37 +0,0 @@ -/* - * \brief 64-bit Task State Segment (TSS) - * \author Adrian-Ken Rueegsegger - * \author Reto Buerki - * \date 2015-02-21 - */ - -/* - * Copyright (C) 2015 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -/* core includes */ -#include -#include - -using namespace Genode; - -extern int _mt_kernel_interrupt_stack; - -void Tss::setup(addr_t const virt_base) -{ - addr_t const stack_addr = - _virt_mtc_addr(virt_base, (addr_t)&_mt_kernel_interrupt_stack); - - this->rsp0 = stack_addr; - this->rsp1 = stack_addr; - this->rsp2 = stack_addr; -} - - -void Tss::load() -{ - asm volatile ("ltr %w0" : : "r" (TSS_SELECTOR)); -}