direct-io.hg

changeset 7383:5487b11faafa

add BT instruction support to VMX MMIO decoder.
Also extends TEST and OR instructions support for 16/32 bit operations,
these are needed for windows.

Signed-off-by: Xin Li <xin.b.li@intel.com>
Signed-off-by: Chengyuan Li <chengyuan.li@intel.com>
Signed-off-by: Nakajima Jun <nakajima.jun@intel.com>
author kaf24@firebug.cl.cam.ac.uk
date Sat Oct 15 07:43:08 2005 +0100 (2005-10-15)
parents 768b04d09dde
children 26862e5458eb
files xen/arch/x86/vmx_io.c xen/arch/x86/vmx_platform.c xen/include/asm-x86/vmx_platform.h
line diff
     1.1 --- a/xen/arch/x86/vmx_io.c	Sat Oct 15 00:20:35 2005 +0100
     1.2 +++ b/xen/arch/x86/vmx_io.c	Sat Oct 15 07:43:08 2005 +0100
     1.3 @@ -624,6 +624,17 @@ static void vmx_mmio_assist(struct cpu_u
     1.4          set_eflags_SF(size, diff, regs);
     1.5          set_eflags_PF(size, diff, regs);
     1.6          break;
     1.7 +
     1.8 +    case INSTR_BT:
     1.9 +        index = operand_index(src);
    1.10 +        value = get_reg_value(size, index, 0, regs);
    1.11 +
    1.12 +        if (p->u.data & (1 << (value & ((1 << 5) - 1))))
    1.13 +            regs->eflags |= X86_EFLAGS_CF;
    1.14 +        else
    1.15 +            regs->eflags &= ~X86_EFLAGS_CF;
    1.16 +
    1.17 +        break;
    1.18      }
    1.19  
    1.20      load_cpu_user_regs(regs);
     2.1 --- a/xen/arch/x86/vmx_platform.c	Sat Oct 15 00:20:35 2005 +0100
     2.2 +++ b/xen/arch/x86/vmx_platform.c	Sat Oct 15 07:43:08 2005 +0100
     2.3 @@ -371,7 +371,7 @@ static int vmx_decode(unsigned char *opc
     2.4      unsigned long eflags;
     2.5      int index, vm86 = 0;
     2.6      unsigned char rex = 0;
     2.7 -    unsigned char tmp_size = 0;
     2.8 +    unsigned char size_reg = 0;
     2.9  
    2.10      init_instruction(instr);
    2.11  
    2.12 @@ -428,33 +428,47 @@ static int vmx_decode(unsigned char *opc
    2.13  
    2.14      case 0x80:
    2.15      case 0x81:
    2.16 -        if (((opcode[1] >> 3) & 7) == 7) { /* cmp $imm, m32/16 */
    2.17 -            instr->instr = INSTR_CMP;
    2.18 +        {
    2.19 +            unsigned char ins_subtype = (opcode[1] >> 3) & 7;
    2.20  
    2.21 -            if (opcode[0] == 0x80)
    2.22 -                GET_OP_SIZE_FOR_BYTE(instr->op_size);
    2.23 -            else
    2.24 +            if (opcode[0] == 0x80) {
    2.25 +                GET_OP_SIZE_FOR_BYTE(size_reg);
    2.26 +                instr->op_size = BYTE;
    2.27 +            } else {
    2.28                  GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
    2.29 +                size_reg = instr->op_size;
    2.30 +            }
    2.31  
    2.32 -            instr->operand[0] = mk_operand(instr->op_size, 0, 0, IMMEDIATE);
    2.33 -            instr->immediate = get_immediate(vm86, opcode+1, BYTE);
    2.34 -            instr->operand[1] = mk_operand(instr->op_size, 0, 0, MEMORY);
    2.35 +            instr->operand[0] = mk_operand(size_reg, 0, 0, IMMEDIATE);
    2.36 +            instr->immediate = get_immediate(vm86, opcode+1, instr->op_size);
    2.37 +            instr->operand[1] = mk_operand(size_reg, 0, 0, MEMORY);
    2.38  
    2.39 -            return DECODE_success;
    2.40 -        } else
    2.41 -            return DECODE_failure;
    2.42 +            switch (ins_subtype) {
    2.43 +                case 7: /* cmp $imm, m32/16 */
    2.44 +                    instr->instr = INSTR_CMP;
    2.45 +                    return DECODE_success;
    2.46 +
    2.47 +                case 1: /* or $imm, m32/16 */
    2.48 +                    instr->instr = INSTR_OR;
    2.49 +                    return DECODE_success;
    2.50 +
    2.51 +                default:
    2.52 +                    printf("%x, This opcode isn't handled yet!\n", *opcode);
    2.53 +                    return DECODE_failure;
    2.54 +            }
    2.55 +        }
    2.56  
    2.57      case 0x84:  /* test m8, r8 */
    2.58          instr->instr = INSTR_TEST;
    2.59          instr->op_size = BYTE;
    2.60 -        GET_OP_SIZE_FOR_BYTE(tmp_size);
    2.61 -        return mem_reg(tmp_size, opcode, instr, rex);
    2.62 +        GET_OP_SIZE_FOR_BYTE(size_reg);
    2.63 +        return mem_reg(size_reg, opcode, instr, rex);
    2.64  
    2.65      case 0x88: /* mov r8, m8 */
    2.66          instr->instr = INSTR_MOV;
    2.67          instr->op_size = BYTE;
    2.68 -        GET_OP_SIZE_FOR_BYTE(tmp_size);
    2.69 -        return reg_mem(tmp_size, opcode, instr, rex);
    2.70 +        GET_OP_SIZE_FOR_BYTE(size_reg);
    2.71 +        return reg_mem(size_reg, opcode, instr, rex);
    2.72  
    2.73      case 0x89: /* mov r32/16, m32/16 */
    2.74          instr->instr = INSTR_MOV;
    2.75 @@ -464,8 +478,8 @@ static int vmx_decode(unsigned char *opc
    2.76      case 0x8A: /* mov m8, r8 */
    2.77          instr->instr = INSTR_MOV;
    2.78          instr->op_size = BYTE;
    2.79 -        GET_OP_SIZE_FOR_BYTE(tmp_size);
    2.80 -        return mem_reg(tmp_size, opcode, instr, rex);
    2.81 +        GET_OP_SIZE_FOR_BYTE(size_reg);
    2.82 +        return mem_reg(size_reg, opcode, instr, rex);
    2.83  
    2.84      case 0x8B: /* mov m32/16, r32/16 */
    2.85          instr->instr = INSTR_MOV;
    2.86 @@ -475,8 +489,8 @@ static int vmx_decode(unsigned char *opc
    2.87      case 0xA0: /* mov <addr>, al */
    2.88          instr->instr = INSTR_MOV;
    2.89          instr->op_size = BYTE;
    2.90 -        GET_OP_SIZE_FOR_BYTE(tmp_size);
    2.91 -        return mem_acc(tmp_size, instr);
    2.92 +        GET_OP_SIZE_FOR_BYTE(size_reg);
    2.93 +        return mem_acc(size_reg, instr);
    2.94  
    2.95      case 0xA1: /* mov <addr>, ax/eax */
    2.96          instr->instr = INSTR_MOV;
    2.97 @@ -486,8 +500,8 @@ static int vmx_decode(unsigned char *opc
    2.98      case 0xA2: /* mov al, <addr> */
    2.99          instr->instr = INSTR_MOV;
   2.100          instr->op_size = BYTE;
   2.101 -        GET_OP_SIZE_FOR_BYTE(tmp_size);
   2.102 -        return acc_mem(tmp_size, instr);
   2.103 +        GET_OP_SIZE_FOR_BYTE(size_reg);
   2.104 +        return acc_mem(size_reg, instr);
   2.105  
   2.106      case 0xA3: /* mov ax/eax, <addr> */
   2.107          instr->instr = INSTR_MOV;
   2.108 @@ -541,13 +555,21 @@ static int vmx_decode(unsigned char *opc
   2.109              return DECODE_failure;
   2.110  
   2.111      case 0xF6:
   2.112 -        if (((opcode[1] >> 3) & 7) == 0) { /* testb $imm8, m8 */
   2.113 +    case 0xF7:
   2.114 +        if (((opcode[1] >> 3) & 7) == 0) { /* test $imm8/16/32, m8/16/32 */
   2.115              instr->instr = INSTR_TEST;
   2.116 -            instr->op_size = BYTE;
   2.117  
   2.118 -            instr->operand[0] = mk_operand(instr->op_size, 0, 0, IMMEDIATE);
   2.119 +            if (opcode[0] == 0xF6) {
   2.120 +                GET_OP_SIZE_FOR_BYTE(size_reg);
   2.121 +                instr->op_size = BYTE;
   2.122 +            } else {
   2.123 +                GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
   2.124 +                size_reg = instr->op_size;
   2.125 +            }
   2.126 +
   2.127 +            instr->operand[0] = mk_operand(size_reg, 0, 0, IMMEDIATE);
   2.128              instr->immediate = get_immediate(vm86, opcode+1, instr->op_size);
   2.129 -            instr->operand[1] = mk_operand(instr->op_size, 0, 0, MEMORY);
   2.130 +            instr->operand[1] = mk_operand(size_reg, 0, 0, MEMORY);
   2.131  
   2.132              return DECODE_success;
   2.133          } else
   2.134 @@ -583,6 +605,14 @@ static int vmx_decode(unsigned char *opc
   2.135          instr->operand[0] = mk_operand(instr->op_size, 0, 0, MEMORY);
   2.136          return DECODE_success;
   2.137  
   2.138 +    case 0xA3: /* bt r32, m32 */
   2.139 +        instr->instr = INSTR_BT;
   2.140 +        index = get_index(opcode + 1, rex);
   2.141 +        instr->op_size = LONG;
   2.142 +        instr->operand[0] = mk_operand(instr->op_size, index, 0, REGISTER);
   2.143 +        instr->operand[1] = mk_operand(instr->op_size, 0, 0, MEMORY);
   2.144 +        return DECODE_success;
   2.145 +
   2.146      default:
   2.147          printf("0f %x, This opcode isn't handled yet\n", *opcode);
   2.148          return DECODE_failure;
   2.149 @@ -843,9 +873,28 @@ void handle_mmio(unsigned long va, unsig
   2.150          mmio_opp->immediate = mmio_inst.immediate;
   2.151  
   2.152          /* send the request and wait for the value */
   2.153 -        send_mmio_req(IOREQ_TYPE_COPY, gpa, 1, mmio_inst.op_size, 0, IOREQ_READ, 0);
   2.154 +        send_mmio_req(IOREQ_TYPE_COPY, gpa, 1,
   2.155 +                      mmio_inst.op_size, 0, IOREQ_READ, 0);
   2.156          break;
   2.157  
   2.158 +    case INSTR_BT:
   2.159 +        {
   2.160 +            unsigned long value = 0;
   2.161 +            int index, size;
   2.162 +
   2.163 +            mmio_opp->instr = mmio_inst.instr;
   2.164 +            mmio_opp->operand[0] = mmio_inst.operand[0]; /* bit offset */
   2.165 +            mmio_opp->operand[1] = mmio_inst.operand[1]; /* bit base */
   2.166 +
   2.167 +            index = operand_index(mmio_inst.operand[0]);
   2.168 +            size = operand_size(mmio_inst.operand[0]);
   2.169 +            value = get_reg_value(size, index, 0, regs);
   2.170 +
   2.171 +            send_mmio_req(IOREQ_TYPE_COPY, gpa + (value >> 5), 1,
   2.172 +                          mmio_inst.op_size, 0, IOREQ_READ, 0);
   2.173 +            break;
   2.174 +        }
   2.175 +
   2.176      default:
   2.177          printf("Unhandled MMIO instruction\n");
   2.178          domain_crash_synchronous();
     3.1 --- a/xen/include/asm-x86/vmx_platform.h	Sat Oct 15 00:20:35 2005 +0100
     3.2 +++ b/xen/include/asm-x86/vmx_platform.h	Sat Oct 15 07:43:08 2005 +0100
     3.3 @@ -27,8 +27,8 @@
     3.4  
     3.5  #define MAX_OPERAND_NUM 2
     3.6  
     3.7 -#define mk_operand(size, index, seg, flag) \
     3.8 -    (((size) << 24) | ((index) << 16) | ((seg) << 8) | (flag))
     3.9 +#define mk_operand(size_reg, index, seg, flag) \
    3.10 +    (((size_reg) << 24) | ((index) << 16) | ((seg) << 8) | (flag))
    3.11  
    3.12  #define operand_size(operand)   \
    3.13        ((operand >> 24) & 0xFF)
    3.14 @@ -63,6 +63,7 @@
    3.15  #define INSTR_MOVZ 8
    3.16  #define INSTR_STOS 9
    3.17  #define INSTR_TEST 10
    3.18 +#define INSTR_BT 11
    3.19  
    3.20  struct instruction {
    3.21      __s8    instr; /* instruction type */