1*69e0a03cSPaolo Bonzini /* 2*69e0a03cSPaolo Bonzini * Copyright (C) 2016 Veertu Inc, 3*69e0a03cSPaolo Bonzini * Copyright (C) 2017 Veertu Inc, 4*69e0a03cSPaolo Bonzini * 5*69e0a03cSPaolo Bonzini * This program is free software; you can redistribute it and/or 6*69e0a03cSPaolo Bonzini * modify it under the terms of the GNU Lesser General Public 7*69e0a03cSPaolo Bonzini * License as published by the Free Software Foundation; either 8*69e0a03cSPaolo Bonzini * version 2 of the License, or (at your option) any later version. 9*69e0a03cSPaolo Bonzini * 10*69e0a03cSPaolo Bonzini * This program is distributed in the hope that it will be useful, 11*69e0a03cSPaolo Bonzini * but WITHOUT ANY WARRANTY; without even the implied warranty of 12*69e0a03cSPaolo Bonzini * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13*69e0a03cSPaolo Bonzini * Lesser General Public License for more details. 14*69e0a03cSPaolo Bonzini * 15*69e0a03cSPaolo Bonzini * You should have received a copy of the GNU Lesser General Public 16*69e0a03cSPaolo Bonzini * License along with this program; if not, see <http://www.gnu.org/licenses/>. 17*69e0a03cSPaolo Bonzini */ 18*69e0a03cSPaolo Bonzini 19*69e0a03cSPaolo Bonzini #pragma once 20*69e0a03cSPaolo Bonzini 21*69e0a03cSPaolo Bonzini #include <sys/types.h> 22*69e0a03cSPaolo Bonzini #include <sys/ioctl.h> 23*69e0a03cSPaolo Bonzini #include <sys/mman.h> 24*69e0a03cSPaolo Bonzini #include <stdarg.h> 25*69e0a03cSPaolo Bonzini #include "qemu-common.h" 26*69e0a03cSPaolo Bonzini #include "x86_gen.h" 27*69e0a03cSPaolo Bonzini 28*69e0a03cSPaolo Bonzini /* exceptions */ 29*69e0a03cSPaolo Bonzini typedef enum x86_exception { 30*69e0a03cSPaolo Bonzini EXCEPTION_DE, /* divide error */ 31*69e0a03cSPaolo Bonzini EXCEPTION_DB, /* debug fault */ 32*69e0a03cSPaolo Bonzini EXCEPTION_NMI, /* non-maskable interrupt */ 33*69e0a03cSPaolo Bonzini EXCEPTION_BP, /* breakpoint trap */ 34*69e0a03cSPaolo Bonzini EXCEPTION_OF, /* overflow trap */ 35*69e0a03cSPaolo Bonzini EXCEPTION_BR, /* boundary range exceeded fault */ 36*69e0a03cSPaolo Bonzini EXCEPTION_UD, /* undefined opcode */ 37*69e0a03cSPaolo Bonzini EXCEPTION_NM, /* device not available */ 38*69e0a03cSPaolo Bonzini EXCEPTION_DF, /* double fault */ 39*69e0a03cSPaolo Bonzini EXCEPTION_RSVD, /* not defined */ 40*69e0a03cSPaolo Bonzini EXCEPTION_TS, /* invalid TSS fault */ 41*69e0a03cSPaolo Bonzini EXCEPTION_NP, /* not present fault */ 42*69e0a03cSPaolo Bonzini EXCEPTION_GP, /* general protection fault */ 43*69e0a03cSPaolo Bonzini EXCEPTION_PF, /* page fault */ 44*69e0a03cSPaolo Bonzini EXCEPTION_RSVD2, /* not defined */ 45*69e0a03cSPaolo Bonzini } x86_exception; 46*69e0a03cSPaolo Bonzini 47*69e0a03cSPaolo Bonzini /* general purpose regs */ 48*69e0a03cSPaolo Bonzini typedef enum x86_reg_name { 49*69e0a03cSPaolo Bonzini REG_RAX = 0, 50*69e0a03cSPaolo Bonzini REG_RCX = 1, 51*69e0a03cSPaolo Bonzini REG_RDX = 2, 52*69e0a03cSPaolo Bonzini REG_RBX = 3, 53*69e0a03cSPaolo Bonzini REG_RSP = 4, 54*69e0a03cSPaolo Bonzini REG_RBP = 5, 55*69e0a03cSPaolo Bonzini REG_RSI = 6, 56*69e0a03cSPaolo Bonzini REG_RDI = 7, 57*69e0a03cSPaolo Bonzini REG_R8 = 8, 58*69e0a03cSPaolo Bonzini REG_R9 = 9, 59*69e0a03cSPaolo Bonzini REG_R10 = 10, 60*69e0a03cSPaolo Bonzini REG_R11 = 11, 61*69e0a03cSPaolo Bonzini REG_R12 = 12, 62*69e0a03cSPaolo Bonzini REG_R13 = 13, 63*69e0a03cSPaolo Bonzini REG_R14 = 14, 64*69e0a03cSPaolo Bonzini REG_R15 = 15, 65*69e0a03cSPaolo Bonzini } x86_reg_name; 66*69e0a03cSPaolo Bonzini 67*69e0a03cSPaolo Bonzini /* segment regs */ 68*69e0a03cSPaolo Bonzini typedef enum x86_reg_segment { 69*69e0a03cSPaolo Bonzini REG_SEG_ES = 0, 70*69e0a03cSPaolo Bonzini REG_SEG_CS = 1, 71*69e0a03cSPaolo Bonzini REG_SEG_SS = 2, 72*69e0a03cSPaolo Bonzini REG_SEG_DS = 3, 73*69e0a03cSPaolo Bonzini REG_SEG_FS = 4, 74*69e0a03cSPaolo Bonzini REG_SEG_GS = 5, 75*69e0a03cSPaolo Bonzini REG_SEG_LDTR = 6, 76*69e0a03cSPaolo Bonzini REG_SEG_TR = 7, 77*69e0a03cSPaolo Bonzini } x86_reg_segment; 78*69e0a03cSPaolo Bonzini 79*69e0a03cSPaolo Bonzini typedef struct x86_register { 80*69e0a03cSPaolo Bonzini union { 81*69e0a03cSPaolo Bonzini struct { 82*69e0a03cSPaolo Bonzini uint64_t rrx; /* full 64 bit */ 83*69e0a03cSPaolo Bonzini }; 84*69e0a03cSPaolo Bonzini struct { 85*69e0a03cSPaolo Bonzini uint32_t erx; /* low 32 bit part */ 86*69e0a03cSPaolo Bonzini uint32_t hi32_unused1; 87*69e0a03cSPaolo Bonzini }; 88*69e0a03cSPaolo Bonzini struct { 89*69e0a03cSPaolo Bonzini uint16_t rx; /* low 16 bit part */ 90*69e0a03cSPaolo Bonzini uint16_t hi16_unused1; 91*69e0a03cSPaolo Bonzini uint32_t hi32_unused2; 92*69e0a03cSPaolo Bonzini }; 93*69e0a03cSPaolo Bonzini struct { 94*69e0a03cSPaolo Bonzini uint8_t lx; /* low 8 bit part */ 95*69e0a03cSPaolo Bonzini uint8_t hx; /* high 8 bit */ 96*69e0a03cSPaolo Bonzini uint16_t hi16_unused2; 97*69e0a03cSPaolo Bonzini uint32_t hi32_unused3; 98*69e0a03cSPaolo Bonzini }; 99*69e0a03cSPaolo Bonzini }; 100*69e0a03cSPaolo Bonzini } __attribute__ ((__packed__)) x86_register; 101*69e0a03cSPaolo Bonzini 102*69e0a03cSPaolo Bonzini typedef enum x86_rflags { 103*69e0a03cSPaolo Bonzini RFLAGS_CF = (1L << 0), 104*69e0a03cSPaolo Bonzini RFLAGS_PF = (1L << 2), 105*69e0a03cSPaolo Bonzini RFLAGS_AF = (1L << 4), 106*69e0a03cSPaolo Bonzini RFLAGS_ZF = (1L << 6), 107*69e0a03cSPaolo Bonzini RFLAGS_SF = (1L << 7), 108*69e0a03cSPaolo Bonzini RFLAGS_TF = (1L << 8), 109*69e0a03cSPaolo Bonzini RFLAGS_IF = (1L << 9), 110*69e0a03cSPaolo Bonzini RFLAGS_DF = (1L << 10), 111*69e0a03cSPaolo Bonzini RFLAGS_OF = (1L << 11), 112*69e0a03cSPaolo Bonzini RFLAGS_IOPL = (3L << 12), 113*69e0a03cSPaolo Bonzini RFLAGS_NT = (1L << 14), 114*69e0a03cSPaolo Bonzini RFLAGS_RF = (1L << 16), 115*69e0a03cSPaolo Bonzini RFLAGS_VM = (1L << 17), 116*69e0a03cSPaolo Bonzini RFLAGS_AC = (1L << 18), 117*69e0a03cSPaolo Bonzini RFLAGS_VIF = (1L << 19), 118*69e0a03cSPaolo Bonzini RFLAGS_VIP = (1L << 20), 119*69e0a03cSPaolo Bonzini RFLAGS_ID = (1L << 21), 120*69e0a03cSPaolo Bonzini } x86_rflags; 121*69e0a03cSPaolo Bonzini 122*69e0a03cSPaolo Bonzini /* rflags register */ 123*69e0a03cSPaolo Bonzini typedef struct x86_reg_flags { 124*69e0a03cSPaolo Bonzini union { 125*69e0a03cSPaolo Bonzini struct { 126*69e0a03cSPaolo Bonzini uint64_t rflags; 127*69e0a03cSPaolo Bonzini }; 128*69e0a03cSPaolo Bonzini struct { 129*69e0a03cSPaolo Bonzini uint32_t eflags; 130*69e0a03cSPaolo Bonzini uint32_t hi32_unused1; 131*69e0a03cSPaolo Bonzini }; 132*69e0a03cSPaolo Bonzini struct { 133*69e0a03cSPaolo Bonzini uint32_t cf:1; 134*69e0a03cSPaolo Bonzini uint32_t unused1:1; 135*69e0a03cSPaolo Bonzini uint32_t pf:1; 136*69e0a03cSPaolo Bonzini uint32_t unused2:1; 137*69e0a03cSPaolo Bonzini uint32_t af:1; 138*69e0a03cSPaolo Bonzini uint32_t unused3:1; 139*69e0a03cSPaolo Bonzini uint32_t zf:1; 140*69e0a03cSPaolo Bonzini uint32_t sf:1; 141*69e0a03cSPaolo Bonzini uint32_t tf:1; 142*69e0a03cSPaolo Bonzini uint32_t ief:1; 143*69e0a03cSPaolo Bonzini uint32_t df:1; 144*69e0a03cSPaolo Bonzini uint32_t of:1; 145*69e0a03cSPaolo Bonzini uint32_t iopl:2; 146*69e0a03cSPaolo Bonzini uint32_t nt:1; 147*69e0a03cSPaolo Bonzini uint32_t unused4:1; 148*69e0a03cSPaolo Bonzini uint32_t rf:1; 149*69e0a03cSPaolo Bonzini uint32_t vm:1; 150*69e0a03cSPaolo Bonzini uint32_t ac:1; 151*69e0a03cSPaolo Bonzini uint32_t vif:1; 152*69e0a03cSPaolo Bonzini uint32_t vip:1; 153*69e0a03cSPaolo Bonzini uint32_t id:1; 154*69e0a03cSPaolo Bonzini uint32_t unused5:10; 155*69e0a03cSPaolo Bonzini uint32_t hi32_unused2; 156*69e0a03cSPaolo Bonzini }; 157*69e0a03cSPaolo Bonzini }; 158*69e0a03cSPaolo Bonzini } __attribute__ ((__packed__)) x86_reg_flags; 159*69e0a03cSPaolo Bonzini 160*69e0a03cSPaolo Bonzini typedef enum x86_reg_efer { 161*69e0a03cSPaolo Bonzini EFER_SCE = (1L << 0), 162*69e0a03cSPaolo Bonzini EFER_LME = (1L << 8), 163*69e0a03cSPaolo Bonzini EFER_LMA = (1L << 10), 164*69e0a03cSPaolo Bonzini EFER_NXE = (1L << 11), 165*69e0a03cSPaolo Bonzini EFER_SVME = (1L << 12), 166*69e0a03cSPaolo Bonzini EFER_FXSR = (1L << 14), 167*69e0a03cSPaolo Bonzini } x86_reg_efer; 168*69e0a03cSPaolo Bonzini 169*69e0a03cSPaolo Bonzini typedef struct x86_efer { 170*69e0a03cSPaolo Bonzini uint64_t efer; 171*69e0a03cSPaolo Bonzini } __attribute__ ((__packed__)) x86_efer; 172*69e0a03cSPaolo Bonzini 173*69e0a03cSPaolo Bonzini typedef enum x86_reg_cr0 { 174*69e0a03cSPaolo Bonzini CR0_PE = (1L << 0), 175*69e0a03cSPaolo Bonzini CR0_MP = (1L << 1), 176*69e0a03cSPaolo Bonzini CR0_EM = (1L << 2), 177*69e0a03cSPaolo Bonzini CR0_TS = (1L << 3), 178*69e0a03cSPaolo Bonzini CR0_ET = (1L << 4), 179*69e0a03cSPaolo Bonzini CR0_NE = (1L << 5), 180*69e0a03cSPaolo Bonzini CR0_WP = (1L << 16), 181*69e0a03cSPaolo Bonzini CR0_AM = (1L << 18), 182*69e0a03cSPaolo Bonzini CR0_NW = (1L << 29), 183*69e0a03cSPaolo Bonzini CR0_CD = (1L << 30), 184*69e0a03cSPaolo Bonzini CR0_PG = (1L << 31), 185*69e0a03cSPaolo Bonzini } x86_reg_cr0; 186*69e0a03cSPaolo Bonzini 187*69e0a03cSPaolo Bonzini typedef enum x86_reg_cr4 { 188*69e0a03cSPaolo Bonzini CR4_VME = (1L << 0), 189*69e0a03cSPaolo Bonzini CR4_PVI = (1L << 1), 190*69e0a03cSPaolo Bonzini CR4_TSD = (1L << 2), 191*69e0a03cSPaolo Bonzini CR4_DE = (1L << 3), 192*69e0a03cSPaolo Bonzini CR4_PSE = (1L << 4), 193*69e0a03cSPaolo Bonzini CR4_PAE = (1L << 5), 194*69e0a03cSPaolo Bonzini CR4_MSE = (1L << 6), 195*69e0a03cSPaolo Bonzini CR4_PGE = (1L << 7), 196*69e0a03cSPaolo Bonzini CR4_PCE = (1L << 8), 197*69e0a03cSPaolo Bonzini CR4_OSFXSR = (1L << 9), 198*69e0a03cSPaolo Bonzini CR4_OSXMMEXCPT = (1L << 10), 199*69e0a03cSPaolo Bonzini CR4_VMXE = (1L << 13), 200*69e0a03cSPaolo Bonzini CR4_SMXE = (1L << 14), 201*69e0a03cSPaolo Bonzini CR4_FSGSBASE = (1L << 16), 202*69e0a03cSPaolo Bonzini CR4_PCIDE = (1L << 17), 203*69e0a03cSPaolo Bonzini CR4_OSXSAVE = (1L << 18), 204*69e0a03cSPaolo Bonzini CR4_SMEP = (1L << 20), 205*69e0a03cSPaolo Bonzini } x86_reg_cr4; 206*69e0a03cSPaolo Bonzini 207*69e0a03cSPaolo Bonzini /* 16 bit Task State Segment */ 208*69e0a03cSPaolo Bonzini typedef struct x86_tss_segment16 { 209*69e0a03cSPaolo Bonzini uint16_t link; 210*69e0a03cSPaolo Bonzini uint16_t sp0; 211*69e0a03cSPaolo Bonzini uint16_t ss0; 212*69e0a03cSPaolo Bonzini uint32_t sp1; 213*69e0a03cSPaolo Bonzini uint16_t ss1; 214*69e0a03cSPaolo Bonzini uint32_t sp2; 215*69e0a03cSPaolo Bonzini uint16_t ss2; 216*69e0a03cSPaolo Bonzini uint16_t ip; 217*69e0a03cSPaolo Bonzini uint16_t flags; 218*69e0a03cSPaolo Bonzini uint16_t ax; 219*69e0a03cSPaolo Bonzini uint16_t cx; 220*69e0a03cSPaolo Bonzini uint16_t dx; 221*69e0a03cSPaolo Bonzini uint16_t bx; 222*69e0a03cSPaolo Bonzini uint16_t sp; 223*69e0a03cSPaolo Bonzini uint16_t bp; 224*69e0a03cSPaolo Bonzini uint16_t si; 225*69e0a03cSPaolo Bonzini uint16_t di; 226*69e0a03cSPaolo Bonzini uint16_t es; 227*69e0a03cSPaolo Bonzini uint16_t cs; 228*69e0a03cSPaolo Bonzini uint16_t ss; 229*69e0a03cSPaolo Bonzini uint16_t ds; 230*69e0a03cSPaolo Bonzini uint16_t ldtr; 231*69e0a03cSPaolo Bonzini } __attribute__((packed)) x86_tss_segment16; 232*69e0a03cSPaolo Bonzini 233*69e0a03cSPaolo Bonzini /* 32 bit Task State Segment */ 234*69e0a03cSPaolo Bonzini typedef struct x86_tss_segment32 { 235*69e0a03cSPaolo Bonzini uint32_t prev_tss; 236*69e0a03cSPaolo Bonzini uint32_t esp0; 237*69e0a03cSPaolo Bonzini uint32_t ss0; 238*69e0a03cSPaolo Bonzini uint32_t esp1; 239*69e0a03cSPaolo Bonzini uint32_t ss1; 240*69e0a03cSPaolo Bonzini uint32_t esp2; 241*69e0a03cSPaolo Bonzini uint32_t ss2; 242*69e0a03cSPaolo Bonzini uint32_t cr3; 243*69e0a03cSPaolo Bonzini uint32_t eip; 244*69e0a03cSPaolo Bonzini uint32_t eflags; 245*69e0a03cSPaolo Bonzini uint32_t eax; 246*69e0a03cSPaolo Bonzini uint32_t ecx; 247*69e0a03cSPaolo Bonzini uint32_t edx; 248*69e0a03cSPaolo Bonzini uint32_t ebx; 249*69e0a03cSPaolo Bonzini uint32_t esp; 250*69e0a03cSPaolo Bonzini uint32_t ebp; 251*69e0a03cSPaolo Bonzini uint32_t esi; 252*69e0a03cSPaolo Bonzini uint32_t edi; 253*69e0a03cSPaolo Bonzini uint32_t es; 254*69e0a03cSPaolo Bonzini uint32_t cs; 255*69e0a03cSPaolo Bonzini uint32_t ss; 256*69e0a03cSPaolo Bonzini uint32_t ds; 257*69e0a03cSPaolo Bonzini uint32_t fs; 258*69e0a03cSPaolo Bonzini uint32_t gs; 259*69e0a03cSPaolo Bonzini uint32_t ldt; 260*69e0a03cSPaolo Bonzini uint16_t trap; 261*69e0a03cSPaolo Bonzini uint16_t iomap_base; 262*69e0a03cSPaolo Bonzini } __attribute__ ((__packed__)) x86_tss_segment32; 263*69e0a03cSPaolo Bonzini 264*69e0a03cSPaolo Bonzini /* 64 bit Task State Segment */ 265*69e0a03cSPaolo Bonzini typedef struct x86_tss_segment64 { 266*69e0a03cSPaolo Bonzini uint32_t unused; 267*69e0a03cSPaolo Bonzini uint64_t rsp0; 268*69e0a03cSPaolo Bonzini uint64_t rsp1; 269*69e0a03cSPaolo Bonzini uint64_t rsp2; 270*69e0a03cSPaolo Bonzini uint64_t unused1; 271*69e0a03cSPaolo Bonzini uint64_t ist1; 272*69e0a03cSPaolo Bonzini uint64_t ist2; 273*69e0a03cSPaolo Bonzini uint64_t ist3; 274*69e0a03cSPaolo Bonzini uint64_t ist4; 275*69e0a03cSPaolo Bonzini uint64_t ist5; 276*69e0a03cSPaolo Bonzini uint64_t ist6; 277*69e0a03cSPaolo Bonzini uint64_t ist7; 278*69e0a03cSPaolo Bonzini uint64_t unused2; 279*69e0a03cSPaolo Bonzini uint16_t unused3; 280*69e0a03cSPaolo Bonzini uint16_t iomap_base; 281*69e0a03cSPaolo Bonzini } __attribute__ ((__packed__)) x86_tss_segment64; 282*69e0a03cSPaolo Bonzini 283*69e0a03cSPaolo Bonzini /* segment descriptors */ 284*69e0a03cSPaolo Bonzini typedef struct x86_segment_descriptor { 285*69e0a03cSPaolo Bonzini uint64_t limit0:16; 286*69e0a03cSPaolo Bonzini uint64_t base0:16; 287*69e0a03cSPaolo Bonzini uint64_t base1:8; 288*69e0a03cSPaolo Bonzini uint64_t type:4; 289*69e0a03cSPaolo Bonzini uint64_t s:1; 290*69e0a03cSPaolo Bonzini uint64_t dpl:2; 291*69e0a03cSPaolo Bonzini uint64_t p:1; 292*69e0a03cSPaolo Bonzini uint64_t limit1:4; 293*69e0a03cSPaolo Bonzini uint64_t avl:1; 294*69e0a03cSPaolo Bonzini uint64_t l:1; 295*69e0a03cSPaolo Bonzini uint64_t db:1; 296*69e0a03cSPaolo Bonzini uint64_t g:1; 297*69e0a03cSPaolo Bonzini uint64_t base2:8; 298*69e0a03cSPaolo Bonzini } __attribute__ ((__packed__)) x86_segment_descriptor; 299*69e0a03cSPaolo Bonzini 300*69e0a03cSPaolo Bonzini static inline uint32_t x86_segment_base(x86_segment_descriptor *desc) 301*69e0a03cSPaolo Bonzini { 302*69e0a03cSPaolo Bonzini return (uint32_t)((desc->base2 << 24) | (desc->base1 << 16) | desc->base0); 303*69e0a03cSPaolo Bonzini } 304*69e0a03cSPaolo Bonzini 305*69e0a03cSPaolo Bonzini static inline void x86_set_segment_base(x86_segment_descriptor *desc, 306*69e0a03cSPaolo Bonzini uint32_t base) 307*69e0a03cSPaolo Bonzini { 308*69e0a03cSPaolo Bonzini desc->base2 = base >> 24; 309*69e0a03cSPaolo Bonzini desc->base1 = (base >> 16) & 0xff; 310*69e0a03cSPaolo Bonzini desc->base0 = base & 0xffff; 311*69e0a03cSPaolo Bonzini } 312*69e0a03cSPaolo Bonzini 313*69e0a03cSPaolo Bonzini static inline uint32_t x86_segment_limit(x86_segment_descriptor *desc) 314*69e0a03cSPaolo Bonzini { 315*69e0a03cSPaolo Bonzini uint32_t limit = (uint32_t)((desc->limit1 << 16) | desc->limit0); 316*69e0a03cSPaolo Bonzini if (desc->g) { 317*69e0a03cSPaolo Bonzini return (limit << 12) | 0xfff; 318*69e0a03cSPaolo Bonzini } 319*69e0a03cSPaolo Bonzini return limit; 320*69e0a03cSPaolo Bonzini } 321*69e0a03cSPaolo Bonzini 322*69e0a03cSPaolo Bonzini static inline void x86_set_segment_limit(x86_segment_descriptor *desc, 323*69e0a03cSPaolo Bonzini uint32_t limit) 324*69e0a03cSPaolo Bonzini { 325*69e0a03cSPaolo Bonzini desc->limit0 = limit & 0xffff; 326*69e0a03cSPaolo Bonzini desc->limit1 = limit >> 16; 327*69e0a03cSPaolo Bonzini } 328*69e0a03cSPaolo Bonzini 329*69e0a03cSPaolo Bonzini typedef struct x86_call_gate { 330*69e0a03cSPaolo Bonzini uint64_t offset0:16; 331*69e0a03cSPaolo Bonzini uint64_t selector:16; 332*69e0a03cSPaolo Bonzini uint64_t param_count:4; 333*69e0a03cSPaolo Bonzini uint64_t reserved:3; 334*69e0a03cSPaolo Bonzini uint64_t type:4; 335*69e0a03cSPaolo Bonzini uint64_t dpl:1; 336*69e0a03cSPaolo Bonzini uint64_t p:1; 337*69e0a03cSPaolo Bonzini uint64_t offset1:16; 338*69e0a03cSPaolo Bonzini } __attribute__ ((__packed__)) x86_call_gate; 339*69e0a03cSPaolo Bonzini 340*69e0a03cSPaolo Bonzini static inline uint32_t x86_call_gate_offset(x86_call_gate *gate) 341*69e0a03cSPaolo Bonzini { 342*69e0a03cSPaolo Bonzini return (uint32_t)((gate->offset1 << 16) | gate->offset0); 343*69e0a03cSPaolo Bonzini } 344*69e0a03cSPaolo Bonzini 345*69e0a03cSPaolo Bonzini #define LDT_SEL 0 346*69e0a03cSPaolo Bonzini #define GDT_SEL 1 347*69e0a03cSPaolo Bonzini 348*69e0a03cSPaolo Bonzini typedef struct x68_segment_selector { 349*69e0a03cSPaolo Bonzini union { 350*69e0a03cSPaolo Bonzini uint16_t sel; 351*69e0a03cSPaolo Bonzini struct { 352*69e0a03cSPaolo Bonzini uint16_t rpl:3; 353*69e0a03cSPaolo Bonzini uint16_t ti:1; 354*69e0a03cSPaolo Bonzini uint16_t index:12; 355*69e0a03cSPaolo Bonzini }; 356*69e0a03cSPaolo Bonzini }; 357*69e0a03cSPaolo Bonzini } __attribute__ ((__packed__)) x68_segment_selector; 358*69e0a03cSPaolo Bonzini 359*69e0a03cSPaolo Bonzini typedef struct lazy_flags { 360*69e0a03cSPaolo Bonzini addr_t result; 361*69e0a03cSPaolo Bonzini addr_t auxbits; 362*69e0a03cSPaolo Bonzini } lazy_flags; 363*69e0a03cSPaolo Bonzini 364*69e0a03cSPaolo Bonzini /* Definition of hvf_x86_state is here */ 365*69e0a03cSPaolo Bonzini struct HVFX86EmulatorState { 366*69e0a03cSPaolo Bonzini int interruptable; 367*69e0a03cSPaolo Bonzini uint64_t fetch_rip; 368*69e0a03cSPaolo Bonzini uint64_t rip; 369*69e0a03cSPaolo Bonzini struct x86_register regs[16]; 370*69e0a03cSPaolo Bonzini struct x86_reg_flags rflags; 371*69e0a03cSPaolo Bonzini struct lazy_flags lflags; 372*69e0a03cSPaolo Bonzini struct x86_efer efer; 373*69e0a03cSPaolo Bonzini uint8_t mmio_buf[4096]; 374*69e0a03cSPaolo Bonzini }; 375*69e0a03cSPaolo Bonzini 376*69e0a03cSPaolo Bonzini /* useful register access macros */ 377*69e0a03cSPaolo Bonzini #define RIP(cpu) (cpu->hvf_emul->rip) 378*69e0a03cSPaolo Bonzini #define EIP(cpu) ((uint32_t)cpu->hvf_emul->rip) 379*69e0a03cSPaolo Bonzini #define RFLAGS(cpu) (cpu->hvf_emul->rflags.rflags) 380*69e0a03cSPaolo Bonzini #define EFLAGS(cpu) (cpu->hvf_emul->rflags.eflags) 381*69e0a03cSPaolo Bonzini 382*69e0a03cSPaolo Bonzini #define RRX(cpu, reg) (cpu->hvf_emul->regs[reg].rrx) 383*69e0a03cSPaolo Bonzini #define RAX(cpu) RRX(cpu, REG_RAX) 384*69e0a03cSPaolo Bonzini #define RCX(cpu) RRX(cpu, REG_RCX) 385*69e0a03cSPaolo Bonzini #define RDX(cpu) RRX(cpu, REG_RDX) 386*69e0a03cSPaolo Bonzini #define RBX(cpu) RRX(cpu, REG_RBX) 387*69e0a03cSPaolo Bonzini #define RSP(cpu) RRX(cpu, REG_RSP) 388*69e0a03cSPaolo Bonzini #define RBP(cpu) RRX(cpu, REG_RBP) 389*69e0a03cSPaolo Bonzini #define RSI(cpu) RRX(cpu, REG_RSI) 390*69e0a03cSPaolo Bonzini #define RDI(cpu) RRX(cpu, REG_RDI) 391*69e0a03cSPaolo Bonzini #define R8(cpu) RRX(cpu, REG_R8) 392*69e0a03cSPaolo Bonzini #define R9(cpu) RRX(cpu, REG_R9) 393*69e0a03cSPaolo Bonzini #define R10(cpu) RRX(cpu, REG_R10) 394*69e0a03cSPaolo Bonzini #define R11(cpu) RRX(cpu, REG_R11) 395*69e0a03cSPaolo Bonzini #define R12(cpu) RRX(cpu, REG_R12) 396*69e0a03cSPaolo Bonzini #define R13(cpu) RRX(cpu, REG_R13) 397*69e0a03cSPaolo Bonzini #define R14(cpu) RRX(cpu, REG_R14) 398*69e0a03cSPaolo Bonzini #define R15(cpu) RRX(cpu, REG_R15) 399*69e0a03cSPaolo Bonzini 400*69e0a03cSPaolo Bonzini #define ERX(cpu, reg) (cpu->hvf_emul->regs[reg].erx) 401*69e0a03cSPaolo Bonzini #define EAX(cpu) ERX(cpu, REG_RAX) 402*69e0a03cSPaolo Bonzini #define ECX(cpu) ERX(cpu, REG_RCX) 403*69e0a03cSPaolo Bonzini #define EDX(cpu) ERX(cpu, REG_RDX) 404*69e0a03cSPaolo Bonzini #define EBX(cpu) ERX(cpu, REG_RBX) 405*69e0a03cSPaolo Bonzini #define ESP(cpu) ERX(cpu, REG_RSP) 406*69e0a03cSPaolo Bonzini #define EBP(cpu) ERX(cpu, REG_RBP) 407*69e0a03cSPaolo Bonzini #define ESI(cpu) ERX(cpu, REG_RSI) 408*69e0a03cSPaolo Bonzini #define EDI(cpu) ERX(cpu, REG_RDI) 409*69e0a03cSPaolo Bonzini 410*69e0a03cSPaolo Bonzini #define RX(cpu, reg) (cpu->hvf_emul->regs[reg].rx) 411*69e0a03cSPaolo Bonzini #define AX(cpu) RX(cpu, REG_RAX) 412*69e0a03cSPaolo Bonzini #define CX(cpu) RX(cpu, REG_RCX) 413*69e0a03cSPaolo Bonzini #define DX(cpu) RX(cpu, REG_RDX) 414*69e0a03cSPaolo Bonzini #define BP(cpu) RX(cpu, REG_RBP) 415*69e0a03cSPaolo Bonzini #define SP(cpu) RX(cpu, REG_RSP) 416*69e0a03cSPaolo Bonzini #define BX(cpu) RX(cpu, REG_RBX) 417*69e0a03cSPaolo Bonzini #define SI(cpu) RX(cpu, REG_RSI) 418*69e0a03cSPaolo Bonzini #define DI(cpu) RX(cpu, REG_RDI) 419*69e0a03cSPaolo Bonzini 420*69e0a03cSPaolo Bonzini #define RL(cpu, reg) (cpu->hvf_emul->regs[reg].lx) 421*69e0a03cSPaolo Bonzini #define AL(cpu) RL(cpu, REG_RAX) 422*69e0a03cSPaolo Bonzini #define CL(cpu) RL(cpu, REG_RCX) 423*69e0a03cSPaolo Bonzini #define DL(cpu) RL(cpu, REG_RDX) 424*69e0a03cSPaolo Bonzini #define BL(cpu) RL(cpu, REG_RBX) 425*69e0a03cSPaolo Bonzini 426*69e0a03cSPaolo Bonzini #define RH(cpu, reg) (cpu->hvf_emul->regs[reg].hx) 427*69e0a03cSPaolo Bonzini #define AH(cpu) RH(cpu, REG_RAX) 428*69e0a03cSPaolo Bonzini #define CH(cpu) RH(cpu, REG_RCX) 429*69e0a03cSPaolo Bonzini #define DH(cpu) RH(cpu, REG_RDX) 430*69e0a03cSPaolo Bonzini #define BH(cpu) RH(cpu, REG_RBX) 431*69e0a03cSPaolo Bonzini 432*69e0a03cSPaolo Bonzini /* deal with GDT/LDT descriptors in memory */ 433*69e0a03cSPaolo Bonzini bool x86_read_segment_descriptor(struct CPUState *cpu, 434*69e0a03cSPaolo Bonzini struct x86_segment_descriptor *desc, 435*69e0a03cSPaolo Bonzini x68_segment_selector sel); 436*69e0a03cSPaolo Bonzini bool x86_write_segment_descriptor(struct CPUState *cpu, 437*69e0a03cSPaolo Bonzini struct x86_segment_descriptor *desc, 438*69e0a03cSPaolo Bonzini x68_segment_selector sel); 439*69e0a03cSPaolo Bonzini 440*69e0a03cSPaolo Bonzini bool x86_read_call_gate(struct CPUState *cpu, struct x86_call_gate *idt_desc, 441*69e0a03cSPaolo Bonzini int gate); 442*69e0a03cSPaolo Bonzini 443*69e0a03cSPaolo Bonzini /* helpers */ 444*69e0a03cSPaolo Bonzini bool x86_is_protected(struct CPUState *cpu); 445*69e0a03cSPaolo Bonzini bool x86_is_real(struct CPUState *cpu); 446*69e0a03cSPaolo Bonzini bool x86_is_v8086(struct CPUState *cpu); 447*69e0a03cSPaolo Bonzini bool x86_is_long_mode(struct CPUState *cpu); 448*69e0a03cSPaolo Bonzini bool x86_is_long64_mode(struct CPUState *cpu); 449*69e0a03cSPaolo Bonzini bool x86_is_paging_mode(struct CPUState *cpu); 450*69e0a03cSPaolo Bonzini bool x86_is_pae_enabled(struct CPUState *cpu); 451*69e0a03cSPaolo Bonzini 452*69e0a03cSPaolo Bonzini addr_t linear_addr(struct CPUState *cpu, addr_t addr, x86_reg_segment seg); 453*69e0a03cSPaolo Bonzini addr_t linear_addr_size(struct CPUState *cpu, addr_t addr, int size, 454*69e0a03cSPaolo Bonzini x86_reg_segment seg); 455*69e0a03cSPaolo Bonzini addr_t linear_rip(struct CPUState *cpu, addr_t rip); 456*69e0a03cSPaolo Bonzini 457*69e0a03cSPaolo Bonzini static inline uint64_t rdtscp(void) 458*69e0a03cSPaolo Bonzini { 459*69e0a03cSPaolo Bonzini uint64_t tsc; 460*69e0a03cSPaolo Bonzini __asm__ __volatile__("rdtscp; " /* serializing read of tsc */ 461*69e0a03cSPaolo Bonzini "shl $32,%%rdx; " /* shift higher 32 bits stored in rdx up */ 462*69e0a03cSPaolo Bonzini "or %%rdx,%%rax" /* and or onto rax */ 463*69e0a03cSPaolo Bonzini : "=a"(tsc) /* output to tsc variable */ 464*69e0a03cSPaolo Bonzini : 465*69e0a03cSPaolo Bonzini : "%rcx", "%rdx"); /* rcx and rdx are clobbered */ 466*69e0a03cSPaolo Bonzini 467*69e0a03cSPaolo Bonzini return tsc; 468*69e0a03cSPaolo Bonzini } 469*69e0a03cSPaolo Bonzini 470