1 /* 2 * Copyright 2014, Paweł Dziepak, pdziepak@quarnos.org. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef _KERNEL_ARCH_X86_64_CPU_H 6 #define _KERNEL_ARCH_X86_64_CPU_H 7 8 9 #include <arch_thread_types.h> 10 11 12 static inline uint64_t 13 x86_read_msr(uint32_t msr) 14 { 15 uint64_t high, low; 16 asm volatile("rdmsr" : "=a" (low), "=d" (high) : "c" (msr)); 17 return (high << 32) | low; 18 } 19 20 21 static inline void 22 x86_write_msr(uint32_t msr, uint64_t value) 23 { 24 asm volatile("wrmsr" : : "a" (value) , "d" (value >> 32), "c" (msr)); 25 } 26 27 28 static inline void 29 x86_context_switch(arch_thread* oldState, arch_thread* newState) 30 { 31 asm volatile( 32 "pushq %%rbp;" 33 "movq $1f, %c[rip](%0);" 34 "movq %%rsp, %c[rsp](%0);" 35 "movq %c[rsp](%1), %%rsp;" 36 "jmp *%c[rip](%1);" 37 "1:" 38 "popq %%rbp;" 39 : 40 : "a" (oldState), "d" (newState), 41 [rsp] "i" (offsetof(arch_thread, current_stack)), 42 [rip] "i" (offsetof(arch_thread, instruction_pointer)) 43 : "rbx", "rcx", "rdi", "rsi", "r8", "r9", "r10", "r11", "r12", "r13", 44 "r14", "r15", "memory"); 45 } 46 47 48 #endif // _KERNEL_ARCH_X86_64_CPU_H 49