1/**
2 * \file
3 * \brief X86 inline asm utilities and defines
4 */
5
6/*
7 * Copyright (c) 2007, 2008, 2009, 2010, 2011, ETH Zurich.
8 * All rights reserved.
9 *
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
13 */
14
15#ifndef K1OM__X86_H
16#define K1OM__X86_H
17
18#include <barrelfish_kpi/types.h>
19#include <barrelfish_kpi/cpu.h>
20#include <arch/x86/x86.h>
21#include <barrelfish_kpi/cpu_arch.h>
22
23/***** RFLAGS flags *****/
24
25/* Fixed flags */
26#define RFLAGS_ALWAYS1  (1 << 1)
27
28/* Status/Control flags */
29#define RFLAGS_CF       (1 << 0)
30#define RFLAGS_PF       (1 << 2)
31#define RFLAGS_AF       (1 << 4)
32#define RFLAGS_ZF       (1 << 6)
33#define RFLAGS_SF       (1 << 7)
34#define RFLAGS_DF       (1 << 10)
35#define RFLAGS_OF       (1 << 11)
36
37/* System flags */
38#define RFLAGS_TF       (1 << 8)
39#define RFLAGS_IF       (1 << 9)
40#define RFLAGS_NT       (1 << 14)
41#define RFLAGS_RF       (1 << 16)
42#define RFLAGS_VM       (1 << 17)
43#define RFLAGS_AC       (1 << 18)
44#define RFLAGS_VIF      (1 << 19)
45#define RFLAGS_VIP      (1 << 20)
46#define RFLAGS_ID       (1 << 21)
47
48/* I/O privilege flags */
49#define RFLAGS_IOPL0    (0 << 12)
50#define RFLAGS_IOPL1    (1 << 12)
51#define RFLAGS_IOPL2    (2 << 12)
52#define RFLAGS_IOPL3    (3 << 12)
53
54/**
55 * State of RFLAGS when executing a user-space program: Enable interrupts
56 */
57#define USER_RFLAGS     (RFLAGS_ALWAYS1 | RFLAGS_IF)
58
59/**
60 * Allowed RFLAGS in user-space. Used when resuming programs.
61 */
62#define USER_RFLAGS_MASK \
63    (RFLAGS_CF | RFLAGS_PF | RFLAGS_AF | RFLAGS_ZF | RFLAGS_SF | RFLAGS_DF | \
64     RFLAGS_OF)
65
66/**
67 * Start address of kernel image in physical memory. This is passed to
68 * the linker also. The bootloader will load us there.
69 */
70#define START_KERNEL_PHYS K1OM_START_KERNEL_PHYS
71
72#ifndef __ASSEMBLER__
73
74/**
75 * Registers automatically saved on kernel stack by CPU
76 */
77enum x86_64_cpu_save_registers {
78    X86_SAVE_RIP, X86_SAVE_CS, X86_SAVE_EFLAGS, X86_SAVE_RSP, X86_SAVE_SS,
79    X86_SAVE_AREA_SIZE
80};
81
82/** \brief Enable FPU */
83static inline void enable_fpu(void)
84{
85    uint64_t cr0;
86    __asm__ __volatile__("mov %%cr0, %%rax" : "=a" (cr0) : );
87    //clear EM
88    cr0 &= ~(1 << 2);
89    //set MP
90    cr0 |= (1 << 1);
91    //set NE
92    cr0 |= (1 << 5);
93    //clear TS
94    cr0 &= ~(1 << 3);
95    __asm__ __volatile__("mov %%rax,%%cr0" : : "a" (cr0));
96    //set OSFXSR
97#ifndef __k1om__
98    uint64_t cr4;
99    /* Enabling SSE instruction os K1OM causes a GP*/
100    __asm__ __volatile__("mov %%cr4, %%rax" : "=a" (cr4) : );
101    cr4 |= (1 << 9);
102    __asm__ __volatile__("mov %%rax,%%cr4" : : "a" (cr4));
103#endif
104    __asm volatile ("finit");
105}
106
107static inline void monitor(lvaddr_t base, uint32_t extensions, uint32_t hints)
108{
109    //panic("MONITOR INSTRUCTION NOT SUPPORTED!");
110   /* __asm volatile("monitor"
111                   : // No output
112                   :
113                   "a" (base),
114                   "c" (extensions),
115                   "d" (hints)
116                   ); */
117}
118
119static inline void mwait(uint32_t hints, uint32_t extensions)
120{
121  //  panic("MWAIT INSTRUCTION NOT SUPPORTED!");
122  /*  __asm volatile("mwait"
123                   : // No output
124                   :
125                   "a" (hints),
126                   "c" (extensions)
127                   ); */
128}
129
130#endif //__ASSEMBLER__
131
132#endif //K1OM__X86_H
133