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
12extern uint16 gFPUControlDefault;
13extern uint32 gFPUMXCSRDefault;
14
15
16static inline uint64_t
17x86_read_msr(uint32_t msr)
18{
19	uint64_t high, low;
20	asm volatile("rdmsr" : "=a" (low), "=d" (high) : "c" (msr));
21	return (high << 32) | low;
22}
23
24
25static inline void
26x86_write_msr(uint32_t msr, uint64_t value)
27{
28	asm volatile("wrmsr" : : "a" (value) , "d" (value >> 32), "c" (msr));
29}
30
31
32static inline void
33x86_context_switch(arch_thread* oldState, arch_thread* newState)
34{
35	asm volatile(
36		"pushq	%%rbp;"
37		"movq	$1f, %c[rip](%0);"
38		"movq	%%rsp, %c[rsp](%0);"
39		"movq	%c[rsp](%1), %%rsp;"
40		"jmp	*%c[rip](%1);"
41		"1:"
42		"popq	%%rbp;"
43		:
44		: "a" (oldState), "d" (newState),
45			[rsp] "i" (offsetof(arch_thread, current_stack)),
46			[rip] "i" (offsetof(arch_thread, instruction_pointer))
47		: "rbx", "rcx", "rdi", "rsi", "r8", "r9", "r10", "r11", "r12", "r13",
48			"r14", "r15", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5",
49			"xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13",
50			"xmm14", "xmm15", "memory");
51	asm volatile("ldmxcsr %0" : : "m" (gFPUMXCSRDefault));
52	asm volatile("fldcw %0" : : "m" (gFPUControlDefault));
53}
54
55
56static inline void
57x86_swap_pgdir(uintptr_t root)
58{
59	asm volatile("movq	%0, %%cr3" : : "r" (root));
60}
61
62
63#endif	// _KERNEL_ARCH_X86_64_CPU_H
64