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 __X86_H 16#define __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 X86_64_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, cr4; 86 uint32_t mxcsr_value = 0x1f80; 87 88 __asm__ __volatile__("mov %%cr0, %%rax" : "=a" (cr0) : ); 89 //clear EM 90 cr0 &= ~(1 << 2); 91 //set MP 92 cr0 |= (1 << 1); 93 //set NE 94 cr0 |= (1 << 5); 95 //clear TS 96 cr0 &= ~(1 << 3); 97 __asm__ __volatile__("mov %%rax,%%cr0" : : "a" (cr0)); 98 //set OSFXSR 99 __asm__ __volatile__("mov %%cr4, %%rax" : "=a" (cr4) : ); 100 cr4 |= (1 << 9); 101 __asm__ __volatile__("mov %%rax,%%cr4" : : "a" (cr4)); 102 __asm volatile ("fninit \n\t" 103 "ldmxcsr %[mxcsr_value] \n\t" 104 : : [mxcsr_value] "m" (mxcsr_value)); 105} 106 107static inline void monitor(lvaddr_t base, uint32_t extensions, uint32_t hints) 108{ 109 __asm volatile("monitor" 110 : // No output 111 : 112 "a" (base), 113 "c" (extensions), 114 "d" (hints) 115 ); 116} 117 118static inline void mwait(uint32_t hints, uint32_t extensions) 119{ 120 __asm volatile("mwait" 121 : // No output 122 : 123 "a" (hints), 124 "c" (extensions) 125 ); 126} 127 128#endif //__ASSEMBLER__ 129 130#endif //__X86_H 131