diff --git a/repos/base-hw/lib/mk/x86_64/core.mk b/repos/base-hw/lib/mk/x86_64/core.mk index 7a390a77b..2e2d32463 100644 --- a/repos/base-hw/lib/mk/x86_64/core.mk +++ b/repos/base-hw/lib/mk/x86_64/core.mk @@ -17,6 +17,7 @@ SRC_S += spec/x86_64/isr.s # add C++ sources SRC_CC += spec/x86_64/kernel/thread_base.cc SRC_CC += spec/x86_64/idt.cc +SRC_CC += spec/x86_64/tss.cc # include less specific configuration include $(REP_DIR)/lib/mk/x86/core.inc 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 new file mode 100644 index 000000000..da8e20790 --- /dev/null +++ b/repos/base-hw/src/core/include/spec/x86_64/tss.h @@ -0,0 +1,53 @@ +#ifndef _TSS_H_ +#define _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; + + /** + * TSS + */ + static Tss _tss asm ("_tss"); + + public: + + /** + * Setup TSS. + */ + static void setup(); + + /** + * Load TSS into TR. + */ + static void load(); + +}__attribute__((packed)); + +#endif /* _TSS_H_ */ diff --git a/repos/base-hw/src/core/spec/x86_64/tss.cc b/repos/base-hw/src/core/spec/x86_64/tss.cc new file mode 100644 index 000000000..b4922bca9 --- /dev/null +++ b/repos/base-hw/src/core/spec/x86_64/tss.cc @@ -0,0 +1,20 @@ +#include "tss.h" + +using namespace Genode; + +extern char kernel_stack[]; + +__attribute__((aligned(8))) Tss Tss::_tss; + +void Tss::setup() +{ + _tss.rsp0 = (addr_t)kernel_stack; + _tss.rsp1 = (addr_t)kernel_stack; + _tss.rsp2 = (addr_t)kernel_stack; +} + + +void Tss::load() +{ + asm volatile ("ltr %w0" : : "r" (TSS_SELECTOR)); +}