/** * \file registers.h * License details are found in the file LICENSE. * \brief * Declare macros and functions to manipulate * Machine Specific Registers (MSR) * \author Taku Shimosawa \par * Copyright (C) 2011 - 2012 Taku Shimosawa * \author Gou Nakamura \par * Copyright (C) 2015 RIKEN AICS */ /* * HISTORY */ #ifndef __HEADER_X86_COMMON_REGISTERS_H #define __HEADER_X86_COMMON_REGISTERS_H #include #define RFLAGS_CF (1 << 0) #define RFLAGS_PF (1 << 2) #define RFLAGS_AF (1 << 4) #define RFLAGS_ZF (1 << 6) #define RFLAGS_SF (1 << 7) #define RFLAGS_TF (1 << 8) #define RFLAGS_IF (1 << 9) #define RFLAGS_DF (1 << 10) #define RFLAGS_OF (1 << 11) #define RFLAGS_IOPL (3 << 12) #define RFLAGS_NT (1 << 14) #define RFLAGS_RF (1 << 16) #define RFLAGS_VM (1 << 17) #define RFLAGS_AC (1 << 18) #define RFLAGS_VIF (1 << 19) #define RFLAGS_VIP (1 << 20) #define RFLAGS_ID (1 << 21) #define DB6_B0 (1 << 0) #define DB6_B1 (1 << 1) #define DB6_B2 (1 << 2) #define DB6_B3 (1 << 3) #define DB6_BD (1 << 13) #define DB6_BS (1 << 14) #define DB6_BT (1 << 15) #define MSR_EFER 0xc0000080 #define MSR_STAR 0xc0000081 #define MSR_LSTAR 0xc0000082 #define MSR_FMASK 0xc0000084 #define MSR_FS_BASE 0xc0000100 #define MSR_GS_BASE 0xc0000101 #define MSR_IA32_APIC_BASE 0x000000001b #define MSR_PLATFORM_INFO 0x000000ce #define MSR_IA32_PERF_CTL 0x00000199 #define MSR_IA32_MISC_ENABLE 0x000001a0 #define MSR_IA32_ENERGY_PERF_BIAS 0x000001b0 #define MSR_NHM_TURBO_RATIO_LIMIT 0x000001ad #define MSR_IA32_CR_PAT 0x00000277 #define MSR_IA32_XSS 0xda0 #define CVAL(event, mask) \ ((((event) & 0xf00) << 24) | ((mask) << 8) | ((event) & 0xff)) #define CVAL2(event, mask, inv, count) \ ((((event) & 0xf00) << 24) | ((mask) << 8) | ((event) & 0xff) | \ ((inv & 1) << 23) | ((count & 0xff) << 24)) /* AMD */ #define MSR_PERF_CTL_0 0xc0010000 #define MSR_PERF_CTR_0 0xc0010004 static inline unsigned long xgetbv(unsigned int index) { unsigned int low, high; asm volatile("xgetbv" : "=a" (low), "=d" (high) : "c" (index)); return low | ((unsigned long)high << 32); } static inline void xsetbv(unsigned int index, unsigned long val) { unsigned int low, high; low = val; high = val >> 32; asm volatile("xsetbv" : : "a" (low), "d" (high), "c" (index)); } static inline void wrmsr(unsigned int idx, unsigned long value) { unsigned int high, low; high = value >> 32; low = value & 0xffffffffU; asm volatile("wrmsr" : : "c" (idx), "a" (low), "d" (high) : "memory"); } static inline unsigned long rdpmc(unsigned int counter) { unsigned int high, low; asm volatile("rdpmc" : "=a" (low), "=d" (high) : "c" (counter)); return (unsigned long)high << 32 | low; } static inline unsigned long rdmsr(unsigned int index) { unsigned int high, low; asm volatile("rdmsr" : "=a" (low), "=d" (high) : "c" (index)); return (unsigned long)high << 32 | low; } static inline unsigned long rdtsc(void) { unsigned int high, low; asm volatile("rdtsc" : "=a" (low), "=d" (high)); return (unsigned long)high << 32 | low; } static inline void set_perfctl(int counter, int event, int mask) { unsigned long value; value = ((unsigned long)(event & 0x700) << 32) | (event & 0xff) | ((mask & 0xff) << 8) | (1 << 18) | (1 << 17); wrmsr(MSR_PERF_CTL_0 + counter, value); } static inline void start_perfctr(int counter) { unsigned long value; value = rdmsr(MSR_PERF_CTL_0 + counter); value |= (1 << 22); wrmsr(MSR_PERF_CTL_0 + counter, value); } static inline void stop_perfctr(int counter) { unsigned long value; value = rdmsr(MSR_PERF_CTL_0 + counter); value &= ~(1 << 22); wrmsr(MSR_PERF_CTL_0 + counter, value); } static inline void clear_perfctl(int counter) { wrmsr(MSR_PERF_CTL_0 + counter, 0); } static inline void set_perfctr(int counter, unsigned long value) { wrmsr(MSR_PERF_CTR_0 + counter, value); } static inline unsigned long read_perfctr(int counter) { return rdpmc(counter); } #define ihk_mc_mb() asm volatile("mfence" : : : "memory"); struct x86_desc_ptr { uint16_t size; uint64_t address; } __attribute__((packed)); struct tss64 { unsigned int reserved0; unsigned long rsp0; unsigned long rsp1; unsigned long rsp2; unsigned int reserved1, reserved2; unsigned long ist[7]; unsigned int reserved3, reserved4; unsigned short reserved5; unsigned short iomap_address; } __attribute__((packed)); struct x86_basic_regs { unsigned long r15; unsigned long r14; unsigned long r13; unsigned long r12; unsigned long rbp; unsigned long rbx; unsigned long r11; unsigned long r10; unsigned long r9; unsigned long r8; unsigned long rax; unsigned long rcx; unsigned long rdx; unsigned long rsi; unsigned long rdi; union { unsigned long orig_rax; /* syscall */ unsigned long error; /* interrupts */ }; unsigned long rip; unsigned long cs; unsigned long rflags; unsigned long rsp; unsigned long ss; }; struct x86_sregs { unsigned long fs_base; unsigned long gs_base; unsigned long ds; unsigned long es; unsigned long fs; unsigned long gs; }; #define REGS_GET_STACK_POINTER(regs) (((struct x86_regs *)regs)->rsp) /* * Page fault error code bits: * * bit 0 == 0: no page found 1: protection fault * bit 1 == 0: read access 1: write access * bit 2 == 0: kernel-mode access 1: user-mode access * bit 3 == 1: use of reserved bit detected * bit 4 == 1: fault was an instruction fetch * * internal use: * bit 29 == 1: Make PF map text modified by ptrace_poketext() * bit 30 == 1: don't use COW page to resolve page fault. */ enum x86_pf_error_code { PF_PROT = 1 << 0, PF_WRITE = 1 << 1, PF_USER = 1 << 2, PF_RSVD = 1 << 3, PF_INSTR = 1 << 4, PF_PATCH = 1 << 29, PF_POPULATE = 1 << 30, }; struct i387_fxsave_struct { unsigned short cwd; unsigned short swd; unsigned short twd; unsigned short fop; union { struct { unsigned long rip; unsigned long rdp; }; struct { unsigned int fip; unsigned int fcs; unsigned int foo; unsigned int fos; }; }; unsigned int mxcsr; unsigned int mxcsr_mask; unsigned int st_space[32]; unsigned int xmm_space[64]; unsigned int padding[12]; union { unsigned int padding1[12]; unsigned int sw_reserved[12]; }; } __attribute__((aligned(16))); struct ymmh_struct { unsigned int ymmh_space[64]; }; struct lwp_struct { unsigned char reserved[128]; }; struct bndreg { unsigned long lower_bound; unsigned long upper_bound; } __attribute__((packed)); struct bndcsr { unsigned long bndcfgu; unsigned long bndstatus; } __attribute__((packed)); struct xsave_hdr_struct { unsigned long xstate_bv; unsigned long xcomp_bv; unsigned long reserved[6]; } __attribute__((packed)); struct xsave_struct { struct i387_fxsave_struct i387; struct xsave_hdr_struct xsave_hdr; struct ymmh_struct ymmh; struct lwp_struct lwp; struct bndreg bndreg[4]; struct bndcsr bndcsr; } __attribute__ ((packed, aligned (64))); typedef struct xsave_struct fp_regs_struct; #endif