qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

x86.h (8483B)


      1 /*
      2  * Copyright (C) 2016 Veertu Inc,
      3  * Copyright (C) 2017 Veertu Inc,
      4  *
      5  * This program is free software; you can redistribute it and/or
      6  * modify it under the terms of the GNU Lesser General Public
      7  * License as published by the Free Software Foundation; either
      8  * version 2.1 of the License, or (at your option) any later version.
      9  *
     10  * This program is distributed in the hope that it will be useful,
     11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13  * Lesser General Public License for more details.
     14  *
     15  * You should have received a copy of the GNU Lesser General Public
     16  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
     17  */
     18 
     19 #ifndef HVF_X86_H
     20 #define HVF_X86_H
     21 
     22 typedef struct x86_register {
     23     union {
     24         struct {
     25             uint64_t rrx;               /* full 64 bit */
     26         };
     27         struct {
     28             uint32_t erx;               /* low 32 bit part */
     29             uint32_t hi32_unused1;
     30         };
     31         struct {
     32             uint16_t rx;                /* low 16 bit part */
     33             uint16_t hi16_unused1;
     34             uint32_t hi32_unused2;
     35         };
     36         struct {
     37             uint8_t lx;                 /* low 8 bit part */
     38             uint8_t hx;                 /* high 8 bit */
     39             uint16_t hi16_unused2;
     40             uint32_t hi32_unused3;
     41         };
     42     };
     43 } __attribute__ ((__packed__)) x86_register;
     44 
     45 /* 16 bit Task State Segment */
     46 typedef struct x86_tss_segment16 {
     47     uint16_t link;
     48     uint16_t sp0;
     49     uint16_t ss0;
     50     uint32_t sp1;
     51     uint16_t ss1;
     52     uint32_t sp2;
     53     uint16_t ss2;
     54     uint16_t ip;
     55     uint16_t flags;
     56     uint16_t ax;
     57     uint16_t cx;
     58     uint16_t dx;
     59     uint16_t bx;
     60     uint16_t sp;
     61     uint16_t bp;
     62     uint16_t si;
     63     uint16_t di;
     64     uint16_t es;
     65     uint16_t cs;
     66     uint16_t ss;
     67     uint16_t ds;
     68     uint16_t ldtr;
     69 } __attribute__((packed)) x86_tss_segment16;
     70 
     71 /* 32 bit Task State Segment */
     72 typedef struct x86_tss_segment32 {
     73     uint32_t prev_tss;
     74     uint32_t esp0;
     75     uint32_t ss0;
     76     uint32_t esp1;
     77     uint32_t ss1;
     78     uint32_t esp2;
     79     uint32_t ss2;
     80     uint32_t cr3;
     81     uint32_t eip;
     82     uint32_t eflags;
     83     uint32_t eax;
     84     uint32_t ecx;
     85     uint32_t edx;
     86     uint32_t ebx;
     87     uint32_t esp;
     88     uint32_t ebp;
     89     uint32_t esi;
     90     uint32_t edi;
     91     uint32_t es;
     92     uint32_t cs;
     93     uint32_t ss;
     94     uint32_t ds;
     95     uint32_t fs;
     96     uint32_t gs;
     97     uint32_t ldt;
     98     uint16_t trap;
     99     uint16_t iomap_base;
    100 } __attribute__ ((__packed__)) x86_tss_segment32;
    101 
    102 /* 64 bit Task State Segment */
    103 typedef struct x86_tss_segment64 {
    104     uint32_t unused;
    105     uint64_t rsp0;
    106     uint64_t rsp1;
    107     uint64_t rsp2;
    108     uint64_t unused1;
    109     uint64_t ist1;
    110     uint64_t ist2;
    111     uint64_t ist3;
    112     uint64_t ist4;
    113     uint64_t ist5;
    114     uint64_t ist6;
    115     uint64_t ist7;
    116     uint64_t unused2;
    117     uint16_t unused3;
    118     uint16_t iomap_base;
    119 } __attribute__ ((__packed__)) x86_tss_segment64;
    120 
    121 /* segment descriptors */
    122 typedef struct x86_segment_descriptor {
    123     uint64_t    limit0:16;
    124     uint64_t    base0:16;
    125     uint64_t    base1:8;
    126     uint64_t    type:4;
    127     uint64_t    s:1;
    128     uint64_t    dpl:2;
    129     uint64_t    p:1;
    130     uint64_t    limit1:4;
    131     uint64_t    avl:1;
    132     uint64_t    l:1;
    133     uint64_t    db:1;
    134     uint64_t    g:1;
    135     uint64_t    base2:8;
    136 } __attribute__ ((__packed__)) x86_segment_descriptor;
    137 
    138 static inline uint32_t x86_segment_base(x86_segment_descriptor *desc)
    139 {
    140     return (uint32_t)((desc->base2 << 24) | (desc->base1 << 16) | desc->base0);
    141 }
    142 
    143 static inline void x86_set_segment_base(x86_segment_descriptor *desc,
    144                                         uint32_t base)
    145 {
    146     desc->base2 = base >> 24;
    147     desc->base1 = (base >> 16) & 0xff;
    148     desc->base0 = base & 0xffff;
    149 }
    150 
    151 static inline uint32_t x86_segment_limit(x86_segment_descriptor *desc)
    152 {
    153     uint32_t limit = (uint32_t)((desc->limit1 << 16) | desc->limit0);
    154     if (desc->g) {
    155         return (limit << 12) | 0xfff;
    156     }
    157     return limit;
    158 }
    159 
    160 static inline void x86_set_segment_limit(x86_segment_descriptor *desc,
    161                                          uint32_t limit)
    162 {
    163     desc->limit0 = limit & 0xffff;
    164     desc->limit1 = limit >> 16;
    165 }
    166 
    167 typedef struct x86_call_gate {
    168     uint64_t offset0:16;
    169     uint64_t selector:16;
    170     uint64_t param_count:4;
    171     uint64_t reserved:3;
    172     uint64_t type:4;
    173     uint64_t dpl:1;
    174     uint64_t p:1;
    175     uint64_t offset1:16;
    176 } __attribute__ ((__packed__)) x86_call_gate;
    177 
    178 static inline uint32_t x86_call_gate_offset(x86_call_gate *gate)
    179 {
    180     return (uint32_t)((gate->offset1 << 16) | gate->offset0);
    181 }
    182 
    183 #define GDT_SEL     0
    184 #define LDT_SEL     1
    185 
    186 typedef struct x68_segment_selector {
    187     union {
    188         uint16_t sel;
    189         struct {
    190             uint16_t rpl:2;
    191             uint16_t ti:1;
    192             uint16_t index:13;
    193         };
    194     };
    195 } __attribute__ ((__packed__)) x68_segment_selector;
    196 
    197 /* useful register access  macros */
    198 #define x86_reg(cpu, reg) ((x86_register *) &cpu->regs[reg])
    199 
    200 #define RRX(cpu, reg)   (x86_reg(cpu, reg)->rrx)
    201 #define RAX(cpu)        RRX(cpu, R_EAX)
    202 #define RCX(cpu)        RRX(cpu, R_ECX)
    203 #define RDX(cpu)        RRX(cpu, R_EDX)
    204 #define RBX(cpu)        RRX(cpu, R_EBX)
    205 #define RSP(cpu)        RRX(cpu, R_ESP)
    206 #define RBP(cpu)        RRX(cpu, R_EBP)
    207 #define RSI(cpu)        RRX(cpu, R_ESI)
    208 #define RDI(cpu)        RRX(cpu, R_EDI)
    209 #define R8(cpu)         RRX(cpu, R_R8)
    210 #define R9(cpu)         RRX(cpu, R_R9)
    211 #define R10(cpu)        RRX(cpu, R_R10)
    212 #define R11(cpu)        RRX(cpu, R_R11)
    213 #define R12(cpu)        RRX(cpu, R_R12)
    214 #define R13(cpu)        RRX(cpu, R_R13)
    215 #define R14(cpu)        RRX(cpu, R_R14)
    216 #define R15(cpu)        RRX(cpu, R_R15)
    217 
    218 #define ERX(cpu, reg)   (x86_reg(cpu, reg)->erx)
    219 #define EAX(cpu)        ERX(cpu, R_EAX)
    220 #define ECX(cpu)        ERX(cpu, R_ECX)
    221 #define EDX(cpu)        ERX(cpu, R_EDX)
    222 #define EBX(cpu)        ERX(cpu, R_EBX)
    223 #define ESP(cpu)        ERX(cpu, R_ESP)
    224 #define EBP(cpu)        ERX(cpu, R_EBP)
    225 #define ESI(cpu)        ERX(cpu, R_ESI)
    226 #define EDI(cpu)        ERX(cpu, R_EDI)
    227 
    228 #define RX(cpu, reg)   (x86_reg(cpu, reg)->rx)
    229 #define AX(cpu)        RX(cpu, R_EAX)
    230 #define CX(cpu)        RX(cpu, R_ECX)
    231 #define DX(cpu)        RX(cpu, R_EDX)
    232 #define BP(cpu)        RX(cpu, R_EBP)
    233 #define SP(cpu)        RX(cpu, R_ESP)
    234 #define BX(cpu)        RX(cpu, R_EBX)
    235 #define SI(cpu)        RX(cpu, R_ESI)
    236 #define DI(cpu)        RX(cpu, R_EDI)
    237 
    238 #define RL(cpu, reg)   (x86_reg(cpu, reg)->lx)
    239 #define AL(cpu)        RL(cpu, R_EAX)
    240 #define CL(cpu)        RL(cpu, R_ECX)
    241 #define DL(cpu)        RL(cpu, R_EDX)
    242 #define BL(cpu)        RL(cpu, R_EBX)
    243 
    244 #define RH(cpu, reg)   (x86_reg(cpu, reg)->hx)
    245 #define AH(cpu)        RH(cpu, R_EAX)
    246 #define CH(cpu)        RH(cpu, R_ECX)
    247 #define DH(cpu)        RH(cpu, R_EDX)
    248 #define BH(cpu)        RH(cpu, R_EBX)
    249 
    250 /* deal with GDT/LDT descriptors in memory */
    251 bool x86_read_segment_descriptor(struct CPUState *cpu,
    252                                  struct x86_segment_descriptor *desc,
    253                                  x68_segment_selector sel);
    254 bool x86_write_segment_descriptor(struct CPUState *cpu,
    255                                   struct x86_segment_descriptor *desc,
    256                                   x68_segment_selector sel);
    257 
    258 bool x86_read_call_gate(struct CPUState *cpu, struct x86_call_gate *idt_desc,
    259                         int gate);
    260 
    261 /* helpers */
    262 bool x86_is_protected(struct CPUState *cpu);
    263 bool x86_is_real(struct CPUState *cpu);
    264 bool x86_is_v8086(struct CPUState *cpu);
    265 bool x86_is_long_mode(struct CPUState *cpu);
    266 bool x86_is_long64_mode(struct CPUState *cpu);
    267 bool x86_is_paging_mode(struct CPUState *cpu);
    268 bool x86_is_pae_enabled(struct CPUState *cpu);
    269 
    270 enum X86Seg;
    271 target_ulong linear_addr(struct CPUState *cpu, target_ulong addr, enum X86Seg seg);
    272 target_ulong linear_addr_size(struct CPUState *cpu, target_ulong addr, int size,
    273                               enum X86Seg seg);
    274 target_ulong linear_rip(struct CPUState *cpu, target_ulong rip);
    275 
    276 static inline uint64_t rdtscp(void)
    277 {
    278     uint64_t tsc;
    279     __asm__ __volatile__("rdtscp; "         /* serializing read of tsc */
    280                          "shl $32,%%rdx; "  /* shift higher 32 bits stored in rdx up */
    281                          "or %%rdx,%%rax"   /* and or onto rax */
    282                          : "=a"(tsc)        /* output to tsc variable */
    283                          :
    284                          : "%rcx", "%rdx"); /* rcx and rdx are clobbered */
    285 
    286     return tsc;
    287 }
    288 
    289 #endif