1f20f9df0SAndreas Färber /* 2f20f9df0SAndreas Färber * x86 gdb server stub 3f20f9df0SAndreas Färber * 4f20f9df0SAndreas Färber * Copyright (c) 2003-2005 Fabrice Bellard 5f20f9df0SAndreas Färber * Copyright (c) 2013 SUSE LINUX Products GmbH 6f20f9df0SAndreas Färber * 7f20f9df0SAndreas Färber * This library is free software; you can redistribute it and/or 8f20f9df0SAndreas Färber * modify it under the terms of the GNU Lesser General Public 9f20f9df0SAndreas Färber * License as published by the Free Software Foundation; either 10f20f9df0SAndreas Färber * version 2 of the License, or (at your option) any later version. 11f20f9df0SAndreas Färber * 12f20f9df0SAndreas Färber * This library is distributed in the hope that it will be useful, 13f20f9df0SAndreas Färber * but WITHOUT ANY WARRANTY; without even the implied warranty of 14f20f9df0SAndreas Färber * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15f20f9df0SAndreas Färber * Lesser General Public License for more details. 16f20f9df0SAndreas Färber * 17f20f9df0SAndreas Färber * You should have received a copy of the GNU Lesser General Public 18f20f9df0SAndreas Färber * License along with this library; if not, see <http://www.gnu.org/licenses/>. 19f20f9df0SAndreas Färber */ 20b6a0aa05SPeter Maydell #include "qemu/osdep.h" 215b50e790SAndreas Färber #include "qemu-common.h" 2233c11879SPaolo Bonzini #include "cpu.h" 235b50e790SAndreas Färber #include "exec/gdbstub.h" 24f20f9df0SAndreas Färber 25f20f9df0SAndreas Färber #ifdef TARGET_X86_64 26f20f9df0SAndreas Färber static const int gpr_map[16] = { 27f20f9df0SAndreas Färber R_EAX, R_EBX, R_ECX, R_EDX, R_ESI, R_EDI, R_EBP, R_ESP, 28f20f9df0SAndreas Färber 8, 9, 10, 11, 12, 13, 14, 15 29f20f9df0SAndreas Färber }; 30f20f9df0SAndreas Färber #else 31f20f9df0SAndreas Färber #define gpr_map gpr_map32 32f20f9df0SAndreas Färber #endif 33f20f9df0SAndreas Färber static const int gpr_map32[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; 34f20f9df0SAndreas Färber 35*7b0f97baSDoug Gale /* 36*7b0f97baSDoug Gale * Keep these in sync with assignment to 37*7b0f97baSDoug Gale * gdb_num_core_regs in target/i386/cpu.c 38*7b0f97baSDoug Gale * and with the machine description 39*7b0f97baSDoug Gale */ 40*7b0f97baSDoug Gale 41*7b0f97baSDoug Gale /* 42*7b0f97baSDoug Gale * SEG: 6 segments, plus fs_base, gs_base, kernel_gs_base 43*7b0f97baSDoug Gale */ 44*7b0f97baSDoug Gale 45*7b0f97baSDoug Gale /* 46*7b0f97baSDoug Gale * general regs -----> 8 or 16 47*7b0f97baSDoug Gale */ 48*7b0f97baSDoug Gale #define IDX_NB_IP 1 49*7b0f97baSDoug Gale #define IDX_NB_FLAGS 1 50*7b0f97baSDoug Gale #define IDX_NB_SEG (6 + 3) 51*7b0f97baSDoug Gale #define IDX_NB_CTL 6 52*7b0f97baSDoug Gale #define IDX_NB_FP 16 53*7b0f97baSDoug Gale /* 54*7b0f97baSDoug Gale * fpu regs ----------> 8 or 16 55*7b0f97baSDoug Gale */ 56*7b0f97baSDoug Gale #define IDX_NB_MXCSR 1 57*7b0f97baSDoug Gale /* 58*7b0f97baSDoug Gale * total ----> 8+1+1+9+6+16+8+1=50 or 16+1+1+9+6+16+16+1=66 59*7b0f97baSDoug Gale */ 60*7b0f97baSDoug Gale 61f20f9df0SAndreas Färber #define IDX_IP_REG CPU_NB_REGS 62*7b0f97baSDoug Gale #define IDX_FLAGS_REG (IDX_IP_REG + IDX_NB_IP) 63*7b0f97baSDoug Gale #define IDX_SEG_REGS (IDX_FLAGS_REG + IDX_NB_FLAGS) 64*7b0f97baSDoug Gale #define IDX_CTL_REGS (IDX_SEG_REGS + IDX_NB_SEG) 65*7b0f97baSDoug Gale #define IDX_FP_REGS (IDX_CTL_REGS + IDX_NB_CTL) 66*7b0f97baSDoug Gale #define IDX_XMM_REGS (IDX_FP_REGS + IDX_NB_FP) 67f20f9df0SAndreas Färber #define IDX_MXCSR_REG (IDX_XMM_REGS + CPU_NB_REGS) 68f20f9df0SAndreas Färber 69*7b0f97baSDoug Gale #define IDX_CTL_CR0_REG (IDX_CTL_REGS + 0) 70*7b0f97baSDoug Gale #define IDX_CTL_CR2_REG (IDX_CTL_REGS + 1) 71*7b0f97baSDoug Gale #define IDX_CTL_CR3_REG (IDX_CTL_REGS + 2) 72*7b0f97baSDoug Gale #define IDX_CTL_CR4_REG (IDX_CTL_REGS + 3) 73*7b0f97baSDoug Gale #define IDX_CTL_CR8_REG (IDX_CTL_REGS + 4) 74*7b0f97baSDoug Gale #define IDX_CTL_EFER_REG (IDX_CTL_REGS + 5) 75*7b0f97baSDoug Gale 76*7b0f97baSDoug Gale #ifdef TARGET_X86_64 77*7b0f97baSDoug Gale #define GDB_FORCE_64 1 78*7b0f97baSDoug Gale #else 79*7b0f97baSDoug Gale #define GDB_FORCE_64 0 80*7b0f97baSDoug Gale #endif 81*7b0f97baSDoug Gale 82*7b0f97baSDoug Gale 835b50e790SAndreas Färber int x86_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) 84f20f9df0SAndreas Färber { 855b50e790SAndreas Färber X86CPU *cpu = X86_CPU(cs); 865b50e790SAndreas Färber CPUX86State *env = &cpu->env; 875b50e790SAndreas Färber 88*7b0f97baSDoug Gale uint64_t tpr; 89*7b0f97baSDoug Gale 90e3592bc9SDoug Evans /* N.B. GDB can't deal with changes in registers or sizes in the middle 91e3592bc9SDoug Evans of a session. So if we're in 32-bit mode on a 64-bit cpu, still act 92e3592bc9SDoug Evans as if we're on a 64-bit cpu. */ 93e3592bc9SDoug Evans 94f20f9df0SAndreas Färber if (n < CPU_NB_REGS) { 95e3592bc9SDoug Evans if (TARGET_LONG_BITS == 64) { 96e3592bc9SDoug Evans if (env->hflags & HF_CS64_MASK) { 97986a2998SAndreas Färber return gdb_get_reg64(mem_buf, env->regs[gpr_map[n]]); 98f20f9df0SAndreas Färber } else if (n < CPU_NB_REGS32) { 99e3592bc9SDoug Evans return gdb_get_reg64(mem_buf, 100e3592bc9SDoug Evans env->regs[gpr_map[n]] & 0xffffffffUL); 101e3592bc9SDoug Evans } else { 102e3592bc9SDoug Evans memset(mem_buf, 0, sizeof(target_ulong)); 103e3592bc9SDoug Evans return sizeof(target_ulong); 104e3592bc9SDoug Evans } 105e3592bc9SDoug Evans } else { 106986a2998SAndreas Färber return gdb_get_reg32(mem_buf, env->regs[gpr_map32[n]]); 107f20f9df0SAndreas Färber } 108f20f9df0SAndreas Färber } else if (n >= IDX_FP_REGS && n < IDX_FP_REGS + 8) { 109f20f9df0SAndreas Färber #ifdef USE_X86LDOUBLE 110f20f9df0SAndreas Färber /* FIXME: byteswap float values - after fixing fpregs layout. */ 111f20f9df0SAndreas Färber memcpy(mem_buf, &env->fpregs[n - IDX_FP_REGS], 10); 112f20f9df0SAndreas Färber #else 113f20f9df0SAndreas Färber memset(mem_buf, 0, 10); 114f20f9df0SAndreas Färber #endif 115f20f9df0SAndreas Färber return 10; 116f20f9df0SAndreas Färber } else if (n >= IDX_XMM_REGS && n < IDX_XMM_REGS + CPU_NB_REGS) { 117f20f9df0SAndreas Färber n -= IDX_XMM_REGS; 118e3592bc9SDoug Evans if (n < CPU_NB_REGS32 || TARGET_LONG_BITS == 64) { 11919cbd87cSEduardo Habkost stq_p(mem_buf, env->xmm_regs[n].ZMM_Q(0)); 12019cbd87cSEduardo Habkost stq_p(mem_buf + 8, env->xmm_regs[n].ZMM_Q(1)); 121f20f9df0SAndreas Färber return 16; 122f20f9df0SAndreas Färber } 123f20f9df0SAndreas Färber } else { 124f20f9df0SAndreas Färber switch (n) { 125f20f9df0SAndreas Färber case IDX_IP_REG: 126e3592bc9SDoug Evans if (TARGET_LONG_BITS == 64) { 127e3592bc9SDoug Evans if (env->hflags & HF_CS64_MASK) { 128986a2998SAndreas Färber return gdb_get_reg64(mem_buf, env->eip); 129f20f9df0SAndreas Färber } else { 130e3592bc9SDoug Evans return gdb_get_reg64(mem_buf, env->eip & 0xffffffffUL); 131e3592bc9SDoug Evans } 132e3592bc9SDoug Evans } else { 133986a2998SAndreas Färber return gdb_get_reg32(mem_buf, env->eip); 134f20f9df0SAndreas Färber } 135f20f9df0SAndreas Färber case IDX_FLAGS_REG: 136986a2998SAndreas Färber return gdb_get_reg32(mem_buf, env->eflags); 137f20f9df0SAndreas Färber 138f20f9df0SAndreas Färber case IDX_SEG_REGS: 139986a2998SAndreas Färber return gdb_get_reg32(mem_buf, env->segs[R_CS].selector); 140f20f9df0SAndreas Färber case IDX_SEG_REGS + 1: 141986a2998SAndreas Färber return gdb_get_reg32(mem_buf, env->segs[R_SS].selector); 142f20f9df0SAndreas Färber case IDX_SEG_REGS + 2: 143986a2998SAndreas Färber return gdb_get_reg32(mem_buf, env->segs[R_DS].selector); 144f20f9df0SAndreas Färber case IDX_SEG_REGS + 3: 145986a2998SAndreas Färber return gdb_get_reg32(mem_buf, env->segs[R_ES].selector); 146f20f9df0SAndreas Färber case IDX_SEG_REGS + 4: 147986a2998SAndreas Färber return gdb_get_reg32(mem_buf, env->segs[R_FS].selector); 148f20f9df0SAndreas Färber case IDX_SEG_REGS + 5: 149986a2998SAndreas Färber return gdb_get_reg32(mem_buf, env->segs[R_GS].selector); 150f20f9df0SAndreas Färber 151*7b0f97baSDoug Gale case IDX_SEG_REGS + 6: 152*7b0f97baSDoug Gale if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { 153*7b0f97baSDoug Gale return gdb_get_reg64(mem_buf, env->segs[R_FS].base); 154*7b0f97baSDoug Gale } 155*7b0f97baSDoug Gale return gdb_get_reg32(mem_buf, env->segs[R_FS].base); 156*7b0f97baSDoug Gale 157*7b0f97baSDoug Gale case IDX_SEG_REGS + 7: 158*7b0f97baSDoug Gale if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { 159*7b0f97baSDoug Gale return gdb_get_reg64(mem_buf, env->segs[R_GS].base); 160*7b0f97baSDoug Gale } 161*7b0f97baSDoug Gale return gdb_get_reg32(mem_buf, env->segs[R_GS].base); 162*7b0f97baSDoug Gale 163*7b0f97baSDoug Gale case IDX_SEG_REGS + 8: 164*7b0f97baSDoug Gale #ifdef TARGET_X86_64 165*7b0f97baSDoug Gale if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { 166*7b0f97baSDoug Gale return gdb_get_reg64(mem_buf, env->kernelgsbase); 167*7b0f97baSDoug Gale } 168*7b0f97baSDoug Gale return gdb_get_reg32(mem_buf, env->kernelgsbase); 169*7b0f97baSDoug Gale #else 170*7b0f97baSDoug Gale return gdb_get_reg32(mem_buf, 0); 171*7b0f97baSDoug Gale #endif 172*7b0f97baSDoug Gale 173f20f9df0SAndreas Färber case IDX_FP_REGS + 8: 174986a2998SAndreas Färber return gdb_get_reg32(mem_buf, env->fpuc); 175f20f9df0SAndreas Färber case IDX_FP_REGS + 9: 176986a2998SAndreas Färber return gdb_get_reg32(mem_buf, (env->fpus & ~0x3800) | 177f20f9df0SAndreas Färber (env->fpstt & 0x7) << 11); 178f20f9df0SAndreas Färber case IDX_FP_REGS + 10: 179986a2998SAndreas Färber return gdb_get_reg32(mem_buf, 0); /* ftag */ 180f20f9df0SAndreas Färber case IDX_FP_REGS + 11: 181986a2998SAndreas Färber return gdb_get_reg32(mem_buf, 0); /* fiseg */ 182f20f9df0SAndreas Färber case IDX_FP_REGS + 12: 183986a2998SAndreas Färber return gdb_get_reg32(mem_buf, 0); /* fioff */ 184f20f9df0SAndreas Färber case IDX_FP_REGS + 13: 185986a2998SAndreas Färber return gdb_get_reg32(mem_buf, 0); /* foseg */ 186f20f9df0SAndreas Färber case IDX_FP_REGS + 14: 187986a2998SAndreas Färber return gdb_get_reg32(mem_buf, 0); /* fooff */ 188f20f9df0SAndreas Färber case IDX_FP_REGS + 15: 189986a2998SAndreas Färber return gdb_get_reg32(mem_buf, 0); /* fop */ 190f20f9df0SAndreas Färber 191f20f9df0SAndreas Färber case IDX_MXCSR_REG: 192986a2998SAndreas Färber return gdb_get_reg32(mem_buf, env->mxcsr); 193*7b0f97baSDoug Gale 194*7b0f97baSDoug Gale case IDX_CTL_CR0_REG: 195*7b0f97baSDoug Gale if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { 196*7b0f97baSDoug Gale return gdb_get_reg64(mem_buf, env->cr[0]); 197*7b0f97baSDoug Gale } 198*7b0f97baSDoug Gale return gdb_get_reg32(mem_buf, env->cr[0]); 199*7b0f97baSDoug Gale 200*7b0f97baSDoug Gale case IDX_CTL_CR2_REG: 201*7b0f97baSDoug Gale if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { 202*7b0f97baSDoug Gale return gdb_get_reg64(mem_buf, env->cr[2]); 203*7b0f97baSDoug Gale } 204*7b0f97baSDoug Gale return gdb_get_reg32(mem_buf, env->cr[2]); 205*7b0f97baSDoug Gale 206*7b0f97baSDoug Gale case IDX_CTL_CR3_REG: 207*7b0f97baSDoug Gale if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { 208*7b0f97baSDoug Gale return gdb_get_reg64(mem_buf, env->cr[3]); 209*7b0f97baSDoug Gale } 210*7b0f97baSDoug Gale return gdb_get_reg32(mem_buf, env->cr[3]); 211*7b0f97baSDoug Gale 212*7b0f97baSDoug Gale case IDX_CTL_CR4_REG: 213*7b0f97baSDoug Gale if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { 214*7b0f97baSDoug Gale return gdb_get_reg64(mem_buf, env->cr[4]); 215*7b0f97baSDoug Gale } 216*7b0f97baSDoug Gale return gdb_get_reg32(mem_buf, env->cr[4]); 217*7b0f97baSDoug Gale 218*7b0f97baSDoug Gale case IDX_CTL_CR8_REG: 219*7b0f97baSDoug Gale #ifdef CONFIG_SOFTMMU 220*7b0f97baSDoug Gale tpr = cpu_get_apic_tpr(cpu->apic_state); 221*7b0f97baSDoug Gale #else 222*7b0f97baSDoug Gale tpr = 0; 223*7b0f97baSDoug Gale #endif 224*7b0f97baSDoug Gale if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { 225*7b0f97baSDoug Gale return gdb_get_reg64(mem_buf, tpr); 226*7b0f97baSDoug Gale } 227*7b0f97baSDoug Gale return gdb_get_reg32(mem_buf, tpr); 228*7b0f97baSDoug Gale 229*7b0f97baSDoug Gale case IDX_CTL_EFER_REG: 230*7b0f97baSDoug Gale if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { 231*7b0f97baSDoug Gale return gdb_get_reg64(mem_buf, env->efer); 232*7b0f97baSDoug Gale } 233*7b0f97baSDoug Gale return gdb_get_reg32(mem_buf, env->efer); 234f20f9df0SAndreas Färber } 235f20f9df0SAndreas Färber } 236f20f9df0SAndreas Färber return 0; 237f20f9df0SAndreas Färber } 238f20f9df0SAndreas Färber 2395b50e790SAndreas Färber static int x86_cpu_gdb_load_seg(X86CPU *cpu, int sreg, uint8_t *mem_buf) 240f20f9df0SAndreas Färber { 2415b50e790SAndreas Färber CPUX86State *env = &cpu->env; 242f20f9df0SAndreas Färber uint16_t selector = ldl_p(mem_buf); 243f20f9df0SAndreas Färber 244f20f9df0SAndreas Färber if (selector != env->segs[sreg].selector) { 245f20f9df0SAndreas Färber #if defined(CONFIG_USER_ONLY) 246f20f9df0SAndreas Färber cpu_x86_load_seg(env, sreg, selector); 247f20f9df0SAndreas Färber #else 248f20f9df0SAndreas Färber unsigned int limit, flags; 249f20f9df0SAndreas Färber target_ulong base; 250f20f9df0SAndreas Färber 251f20f9df0SAndreas Färber if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) { 252b98dbc90SPaolo Bonzini int dpl = (env->eflags & VM_MASK) ? 3 : 0; 253f20f9df0SAndreas Färber base = selector << 4; 254f20f9df0SAndreas Färber limit = 0xffff; 255b98dbc90SPaolo Bonzini flags = DESC_P_MASK | DESC_S_MASK | DESC_W_MASK | 256b98dbc90SPaolo Bonzini DESC_A_MASK | (dpl << DESC_DPL_SHIFT); 257f20f9df0SAndreas Färber } else { 258f20f9df0SAndreas Färber if (!cpu_x86_get_descr_debug(env, selector, &base, &limit, 259f20f9df0SAndreas Färber &flags)) { 260f20f9df0SAndreas Färber return 4; 261f20f9df0SAndreas Färber } 262f20f9df0SAndreas Färber } 263f20f9df0SAndreas Färber cpu_x86_load_seg_cache(env, sreg, selector, base, limit, flags); 264f20f9df0SAndreas Färber #endif 265f20f9df0SAndreas Färber } 266f20f9df0SAndreas Färber return 4; 267f20f9df0SAndreas Färber } 268f20f9df0SAndreas Färber 2695b50e790SAndreas Färber int x86_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) 270f20f9df0SAndreas Färber { 2715b50e790SAndreas Färber X86CPU *cpu = X86_CPU(cs); 2725b50e790SAndreas Färber CPUX86State *env = &cpu->env; 273f20f9df0SAndreas Färber uint32_t tmp; 274f20f9df0SAndreas Färber 275e3592bc9SDoug Evans /* N.B. GDB can't deal with changes in registers or sizes in the middle 276e3592bc9SDoug Evans of a session. So if we're in 32-bit mode on a 64-bit cpu, still act 277e3592bc9SDoug Evans as if we're on a 64-bit cpu. */ 278e3592bc9SDoug Evans 279f20f9df0SAndreas Färber if (n < CPU_NB_REGS) { 280e3592bc9SDoug Evans if (TARGET_LONG_BITS == 64) { 281e3592bc9SDoug Evans if (env->hflags & HF_CS64_MASK) { 282f20f9df0SAndreas Färber env->regs[gpr_map[n]] = ldtul_p(mem_buf); 283e3592bc9SDoug Evans } else if (n < CPU_NB_REGS32) { 284e3592bc9SDoug Evans env->regs[gpr_map[n]] = ldtul_p(mem_buf) & 0xffffffffUL; 285e3592bc9SDoug Evans } 286f20f9df0SAndreas Färber return sizeof(target_ulong); 287f20f9df0SAndreas Färber } else if (n < CPU_NB_REGS32) { 288f20f9df0SAndreas Färber n = gpr_map32[n]; 289f20f9df0SAndreas Färber env->regs[n] &= ~0xffffffffUL; 290f20f9df0SAndreas Färber env->regs[n] |= (uint32_t)ldl_p(mem_buf); 291f20f9df0SAndreas Färber return 4; 292f20f9df0SAndreas Färber } 293f20f9df0SAndreas Färber } else if (n >= IDX_FP_REGS && n < IDX_FP_REGS + 8) { 294f20f9df0SAndreas Färber #ifdef USE_X86LDOUBLE 295f20f9df0SAndreas Färber /* FIXME: byteswap float values - after fixing fpregs layout. */ 296f20f9df0SAndreas Färber memcpy(&env->fpregs[n - IDX_FP_REGS], mem_buf, 10); 297f20f9df0SAndreas Färber #endif 298f20f9df0SAndreas Färber return 10; 299f20f9df0SAndreas Färber } else if (n >= IDX_XMM_REGS && n < IDX_XMM_REGS + CPU_NB_REGS) { 300f20f9df0SAndreas Färber n -= IDX_XMM_REGS; 301e3592bc9SDoug Evans if (n < CPU_NB_REGS32 || TARGET_LONG_BITS == 64) { 30219cbd87cSEduardo Habkost env->xmm_regs[n].ZMM_Q(0) = ldq_p(mem_buf); 30319cbd87cSEduardo Habkost env->xmm_regs[n].ZMM_Q(1) = ldq_p(mem_buf + 8); 304f20f9df0SAndreas Färber return 16; 305f20f9df0SAndreas Färber } 306f20f9df0SAndreas Färber } else { 307f20f9df0SAndreas Färber switch (n) { 308f20f9df0SAndreas Färber case IDX_IP_REG: 309e3592bc9SDoug Evans if (TARGET_LONG_BITS == 64) { 310e3592bc9SDoug Evans if (env->hflags & HF_CS64_MASK) { 311f20f9df0SAndreas Färber env->eip = ldq_p(mem_buf); 312e3592bc9SDoug Evans } else { 313e3592bc9SDoug Evans env->eip = ldq_p(mem_buf) & 0xffffffffUL; 314e3592bc9SDoug Evans } 315f20f9df0SAndreas Färber return 8; 316f20f9df0SAndreas Färber } else { 317f20f9df0SAndreas Färber env->eip &= ~0xffffffffUL; 318f20f9df0SAndreas Färber env->eip |= (uint32_t)ldl_p(mem_buf); 319f20f9df0SAndreas Färber return 4; 320f20f9df0SAndreas Färber } 321f20f9df0SAndreas Färber case IDX_FLAGS_REG: 322f20f9df0SAndreas Färber env->eflags = ldl_p(mem_buf); 323f20f9df0SAndreas Färber return 4; 324f20f9df0SAndreas Färber 325f20f9df0SAndreas Färber case IDX_SEG_REGS: 3265b50e790SAndreas Färber return x86_cpu_gdb_load_seg(cpu, R_CS, mem_buf); 327f20f9df0SAndreas Färber case IDX_SEG_REGS + 1: 3285b50e790SAndreas Färber return x86_cpu_gdb_load_seg(cpu, R_SS, mem_buf); 329f20f9df0SAndreas Färber case IDX_SEG_REGS + 2: 3305b50e790SAndreas Färber return x86_cpu_gdb_load_seg(cpu, R_DS, mem_buf); 331f20f9df0SAndreas Färber case IDX_SEG_REGS + 3: 3325b50e790SAndreas Färber return x86_cpu_gdb_load_seg(cpu, R_ES, mem_buf); 333f20f9df0SAndreas Färber case IDX_SEG_REGS + 4: 3345b50e790SAndreas Färber return x86_cpu_gdb_load_seg(cpu, R_FS, mem_buf); 335f20f9df0SAndreas Färber case IDX_SEG_REGS + 5: 3365b50e790SAndreas Färber return x86_cpu_gdb_load_seg(cpu, R_GS, mem_buf); 337f20f9df0SAndreas Färber 338*7b0f97baSDoug Gale case IDX_SEG_REGS + 6: 339*7b0f97baSDoug Gale if (env->hflags & HF_CS64_MASK) { 340*7b0f97baSDoug Gale env->segs[R_FS].base = ldq_p(mem_buf); 341*7b0f97baSDoug Gale return 8; 342*7b0f97baSDoug Gale } 343*7b0f97baSDoug Gale env->segs[R_FS].base = ldl_p(mem_buf); 344*7b0f97baSDoug Gale return 4; 345*7b0f97baSDoug Gale 346*7b0f97baSDoug Gale case IDX_SEG_REGS + 7: 347*7b0f97baSDoug Gale if (env->hflags & HF_CS64_MASK) { 348*7b0f97baSDoug Gale env->segs[R_GS].base = ldq_p(mem_buf); 349*7b0f97baSDoug Gale return 8; 350*7b0f97baSDoug Gale } 351*7b0f97baSDoug Gale env->segs[R_GS].base = ldl_p(mem_buf); 352*7b0f97baSDoug Gale return 4; 353*7b0f97baSDoug Gale 354*7b0f97baSDoug Gale #ifdef TARGET_X86_64 355*7b0f97baSDoug Gale case IDX_SEG_REGS + 8: 356*7b0f97baSDoug Gale if (env->hflags & HF_CS64_MASK) { 357*7b0f97baSDoug Gale env->kernelgsbase = ldq_p(mem_buf); 358*7b0f97baSDoug Gale return 8; 359*7b0f97baSDoug Gale } 360*7b0f97baSDoug Gale env->kernelgsbase = ldl_p(mem_buf); 361*7b0f97baSDoug Gale return 4; 362*7b0f97baSDoug Gale #endif 363*7b0f97baSDoug Gale 364f20f9df0SAndreas Färber case IDX_FP_REGS + 8: 3655bde1407SPavel Dovgalyuk cpu_set_fpuc(env, ldl_p(mem_buf)); 366f20f9df0SAndreas Färber return 4; 367f20f9df0SAndreas Färber case IDX_FP_REGS + 9: 368f20f9df0SAndreas Färber tmp = ldl_p(mem_buf); 369f20f9df0SAndreas Färber env->fpstt = (tmp >> 11) & 7; 370f20f9df0SAndreas Färber env->fpus = tmp & ~0x3800; 371f20f9df0SAndreas Färber return 4; 372f20f9df0SAndreas Färber case IDX_FP_REGS + 10: /* ftag */ 373f20f9df0SAndreas Färber return 4; 374f20f9df0SAndreas Färber case IDX_FP_REGS + 11: /* fiseg */ 375f20f9df0SAndreas Färber return 4; 376f20f9df0SAndreas Färber case IDX_FP_REGS + 12: /* fioff */ 377f20f9df0SAndreas Färber return 4; 378f20f9df0SAndreas Färber case IDX_FP_REGS + 13: /* foseg */ 379f20f9df0SAndreas Färber return 4; 380f20f9df0SAndreas Färber case IDX_FP_REGS + 14: /* fooff */ 381f20f9df0SAndreas Färber return 4; 382f20f9df0SAndreas Färber case IDX_FP_REGS + 15: /* fop */ 383f20f9df0SAndreas Färber return 4; 384f20f9df0SAndreas Färber 385f20f9df0SAndreas Färber case IDX_MXCSR_REG: 3864e47e39aSRichard Henderson cpu_set_mxcsr(env, ldl_p(mem_buf)); 387f20f9df0SAndreas Färber return 4; 388*7b0f97baSDoug Gale 389*7b0f97baSDoug Gale case IDX_CTL_CR0_REG: 390*7b0f97baSDoug Gale if (env->hflags & HF_CS64_MASK) { 391*7b0f97baSDoug Gale cpu_x86_update_cr0(env, ldq_p(mem_buf)); 392*7b0f97baSDoug Gale return 8; 393*7b0f97baSDoug Gale } 394*7b0f97baSDoug Gale cpu_x86_update_cr0(env, ldl_p(mem_buf)); 395*7b0f97baSDoug Gale return 4; 396*7b0f97baSDoug Gale 397*7b0f97baSDoug Gale case IDX_CTL_CR2_REG: 398*7b0f97baSDoug Gale if (env->hflags & HF_CS64_MASK) { 399*7b0f97baSDoug Gale env->cr[2] = ldq_p(mem_buf); 400*7b0f97baSDoug Gale return 8; 401*7b0f97baSDoug Gale } 402*7b0f97baSDoug Gale env->cr[2] = ldl_p(mem_buf); 403*7b0f97baSDoug Gale return 4; 404*7b0f97baSDoug Gale 405*7b0f97baSDoug Gale case IDX_CTL_CR3_REG: 406*7b0f97baSDoug Gale if (env->hflags & HF_CS64_MASK) { 407*7b0f97baSDoug Gale cpu_x86_update_cr3(env, ldq_p(mem_buf)); 408*7b0f97baSDoug Gale return 8; 409*7b0f97baSDoug Gale } 410*7b0f97baSDoug Gale cpu_x86_update_cr3(env, ldl_p(mem_buf)); 411*7b0f97baSDoug Gale return 4; 412*7b0f97baSDoug Gale 413*7b0f97baSDoug Gale case IDX_CTL_CR4_REG: 414*7b0f97baSDoug Gale if (env->hflags & HF_CS64_MASK) { 415*7b0f97baSDoug Gale cpu_x86_update_cr4(env, ldq_p(mem_buf)); 416*7b0f97baSDoug Gale return 8; 417*7b0f97baSDoug Gale } 418*7b0f97baSDoug Gale cpu_x86_update_cr4(env, ldl_p(mem_buf)); 419*7b0f97baSDoug Gale return 4; 420*7b0f97baSDoug Gale 421*7b0f97baSDoug Gale case IDX_CTL_CR8_REG: 422*7b0f97baSDoug Gale if (env->hflags & HF_CS64_MASK) { 423*7b0f97baSDoug Gale #ifdef CONFIG_SOFTMMU 424*7b0f97baSDoug Gale cpu_set_apic_tpr(cpu->apic_state, ldq_p(mem_buf)); 425*7b0f97baSDoug Gale #endif 426*7b0f97baSDoug Gale return 8; 427*7b0f97baSDoug Gale } 428*7b0f97baSDoug Gale #ifdef CONFIG_SOFTMMU 429*7b0f97baSDoug Gale cpu_set_apic_tpr(cpu->apic_state, ldl_p(mem_buf)); 430*7b0f97baSDoug Gale #endif 431*7b0f97baSDoug Gale return 4; 432*7b0f97baSDoug Gale 433*7b0f97baSDoug Gale case IDX_CTL_EFER_REG: 434*7b0f97baSDoug Gale if (env->hflags & HF_CS64_MASK) { 435*7b0f97baSDoug Gale cpu_load_efer(env, ldq_p(mem_buf)); 436*7b0f97baSDoug Gale return 8; 437*7b0f97baSDoug Gale } 438*7b0f97baSDoug Gale cpu_load_efer(env, ldl_p(mem_buf)); 439*7b0f97baSDoug Gale return 4; 440*7b0f97baSDoug Gale 441f20f9df0SAndreas Färber } 442f20f9df0SAndreas Färber } 443f20f9df0SAndreas Färber /* Unrecognised register. */ 444f20f9df0SAndreas Färber return 0; 445f20f9df0SAndreas Färber } 446