static void test_ivshmem_single(void) { IVState state, *s; uint32_t data[1024]; int i; setup_vm(&state); s = &state; /* initial state of readable registers */ g_assert_cmpuint(in_reg(s, INTRMASK), ==, 0); g_assert_cmpuint(in_reg(s, INTRSTATUS), ==, 0); g_assert_cmpuint(in_reg(s, IVPOSITION), ==, 0); /* trigger interrupt via registers */ out_reg(s, INTRMASK, 0xffffffff); g_assert_cmpuint(in_reg(s, INTRMASK), ==, 0xffffffff); out_reg(s, INTRSTATUS, 1); /* check interrupt status */ g_assert_cmpuint(in_reg(s, INTRSTATUS), ==, 1); /* reading clears */ g_assert_cmpuint(in_reg(s, INTRSTATUS), ==, 0); /* TODO intercept actual interrupt (needs qtest work) */ /* invalid register access */ out_reg(s, IVPOSITION, 1); in_reg(s, DOORBELL); /* ring the (non-functional) doorbell */ out_reg(s, DOORBELL, 8 << 16); /* write shared memory */ for (i = 0; i < G_N_ELEMENTS(data); i++) { data[i] = i; } write_mem(s, 0, data, sizeof(data)); /* verify write */ for (i = 0; i < G_N_ELEMENTS(data); i++) { g_assert_cmpuint(((uint32_t *)tmpshmem)[i], ==, i); } /* read it back and verify read */ memset(data, 0, sizeof(data)); read_mem(s, 0, data, sizeof(data)); for (i = 0; i < G_N_ELEMENTS(data); i++) { g_assert_cmpuint(data[i], ==, i); } cleanup_vm(s); }
static int set_mode(uint32 width, uint32 height) { out_reg(SVGA_REG_WIDTH, width); out_reg(SVGA_REG_HEIGHT, height); vcons.fb_offset = in_reg(SVGA_REG_FB_OFFSET); vcons.bytes_per_line = in_reg(SVGA_REG_BYTES_PER_LINE); vcons.red_mask = in_reg(SVGA_REG_RED_MASK); vcons.green_mask = in_reg(SVGA_REG_GREEN_MASK); vcons.blue_mask = in_reg(SVGA_REG_BLUE_MASK); out_reg(SVGA_REG_ENABLE, 1); vcons.scrn_width = width; vcons.scrn_height = height; return 0; }
static void writeFIFO(uint32 value) { uint32* vmwareFIFO = (uint32*)vcons.fifo_base; /* Need to sync? */ if ((vmwareFIFO[SVGA_FIFO_NEXT_CMD] + sizeof(uint32) == vmwareFIFO[SVGA_FIFO_STOP]) || (vmwareFIFO[SVGA_FIFO_NEXT_CMD] == vmwareFIFO[SVGA_FIFO_MAX] - sizeof(uint32) && vmwareFIFO[SVGA_FIFO_STOP] == vmwareFIFO[SVGA_FIFO_MIN])) { out_reg(SVGA_REG_SYNC, 1); while (in_reg(SVGA_REG_BUSY)) ; } vmwareFIFO[vmwareFIFO[SVGA_FIFO_NEXT_CMD] / sizeof(uint32)] = value; if(vmwareFIFO[SVGA_FIFO_NEXT_CMD] == vmwareFIFO[SVGA_FIFO_MAX] - sizeof(uint32)) { vmwareFIFO[SVGA_FIFO_NEXT_CMD] = vmwareFIFO[SVGA_FIFO_MIN]; } else { vmwareFIFO[SVGA_FIFO_NEXT_CMD] += sizeof(uint32); } // vmwareFIFO[SVGA_FIFO_NEXT_CMD] += sizeof(uint32); // if (vmwareFIFO[SVGA_FIFO_NEXT_CMD] == vmwareFIFO[SVGA_FIFO_MAX]) // { // vmwareFIFO[SVGA_FIFO_NEXT_CMD] = vmwareFIFO[SVGA_FIFO_MIN]; // } }
//---------------------------------------------------------------------- bool outop(op_t &op) { switch ( op.type ) { case o_void: return 0; case o_reg: out_operators_begin(op); out_reg(op); out_symbol_shift(op, false); out_operators_end(op); out_symbol_shift(op, true); break; case o_relop: out_relop(op); break; case o_shift: out_shift(op.value); break; case o_imm: if (op.tms_prefix == 0) out_symbol('#'); else out_symbol(op.tms_prefix); if (op.tms_signed) OutValue(op, OOFS_IFSIGN|OOF_SIGNED|OOFW_IMM); else OutValue(op, OOFW_IMM); out_symbol_shift(op); break; case o_near: out_address(op); break; case o_mem: case o_io: out_operators_begin(op); out_address(op); out_symbol_shift(op, false); out_operators_end(op); out_symbol_shift(op, true); break; case o_cond: out_cond(op); break; default: error("interr: out"); break; } return 1; }
static void init_fifo() { uint32* vmwareFIFO = (uint32*)vcons.fifo_base; vmwareFIFO[SVGA_FIFO_MIN] = 16; vmwareFIFO[SVGA_FIFO_MAX] = vcons.fifo_size; vmwareFIFO[SVGA_FIFO_NEXT_CMD] = 16; vmwareFIFO[SVGA_FIFO_STOP] = 16; out_reg(SVGA_REG_CONFIG_DONE, 1); }
static void out_reg_if_bit(ushort reg, uval_t value, int bit) { if ( (value & bit) == bit ) { if ( print_comma ) { out_symbol(','); OutChar(' '); } out_reg(reg); print_comma = true; } }
// Output an operand bool outop(op_t &op) { switch ( op.type ) { // Data / Code memory address case o_near: case o_mem: BEG_TAG(op); out_addr(op); END_TAG(op); break; // Immediate value case o_imm: BEG_TAG(op); { const ioport_t * port = find_sym(op.value); // this immediate is represented in the .cfg file if ( port != NULL ) // output the port name instead of the numeric value out_line(port->name, COLOR_IMPNAME); // otherwise, simply print the value else out_imm(op); } END_TAG(op); break; // Displacement case o_displ: out_addr(op, false); out_symbol('('); out_reg(op); out_symbol(')'); break; // Register case o_reg: BEG_TAG(op); out_reg(op); END_TAG(op); if ( is_reg_with_bit(op) ) { out_symbol('.'); if ( is_bit_compl(op) ) out_symbol('!'); out_imm(op, true); } break; // Phrase case o_phrase: switch ( op.specflag2 ) { case fPI: // post increment out_symbol('('); out_reg(op); out_symbol(')'); out_symbol('+'); break; case fPD: // pre decrement out_symbol('-'); out_symbol('('); out_reg(op); out_symbol(')'); break; case fDISP: // displacement out_reg(op); out_symbol('('); { ushort reg = op.specflag2 << 8; reg |= op.specflag3; out_reg(reg); } out_symbol(')'); break; default: IDA_ERROR("Invalid phrase type in outop()"); } break; // No operand case o_void: break; default: IDA_ERROR("Invalid op.type in outop()"); } return 1; }
// Output an operand as a register static void out_reg(op_t &op) { out_reg(op.reg); }
static void test_ivshmem_server(void) { IVState state1, state2, *s1, *s2; ServerThread thread; IvshmemServer server; int ret, vm1, vm2; int nvectors = 2; guint64 end_time = g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND; ret = ivshmem_server_init(&server, tmpserver, tmpshm, true, TMPSHMSIZE, nvectors, g_test_verbose()); g_assert_cmpint(ret, ==, 0); ret = ivshmem_server_start(&server); g_assert_cmpint(ret, ==, 0); thread.server = &server; ret = pipe(thread.pipe); g_assert_cmpint(ret, ==, 0); thread.thread = g_thread_new("ivshmem-server", server_thread, &thread); g_assert(thread.thread != NULL); setup_vm_with_server(&state1, nvectors); s1 = &state1; setup_vm_with_server(&state2, nvectors); s2 = &state2; /* check got different VM ids */ vm1 = in_reg(s1, IVPOSITION); vm2 = in_reg(s2, IVPOSITION); g_assert_cmpint(vm1, >=, 0); g_assert_cmpint(vm2, >=, 0); g_assert_cmpint(vm1, !=, vm2); /* check number of MSI-X vectors */ ret = qpci_msix_table_size(s1->dev); g_assert_cmpuint(ret, ==, nvectors); /* TODO test behavior before MSI-X is enabled */ /* ping vm2 -> vm1 on vector 0 */ ret = qpci_msix_pending(s1->dev, 0); g_assert_cmpuint(ret, ==, 0); out_reg(s2, DOORBELL, vm1 << 16); do { g_usleep(10000); ret = qpci_msix_pending(s1->dev, 0); } while (ret == 0 && g_get_monotonic_time() < end_time); g_assert_cmpuint(ret, !=, 0); /* ping vm1 -> vm2 on vector 1 */ ret = qpci_msix_pending(s2->dev, 1); g_assert_cmpuint(ret, ==, 0); out_reg(s1, DOORBELL, vm2 << 16 | 1); do { g_usleep(10000); ret = qpci_msix_pending(s2->dev, 1); } while (ret == 0 && g_get_monotonic_time() < end_time); g_assert_cmpuint(ret, !=, 0); cleanup_vm(s2); cleanup_vm(s1); if (qemu_write_full(thread.pipe[1], "q", 1) != 1) { g_error("qemu_write_full: %s", g_strerror(errno)); } g_thread_join(thread.thread); ivshmem_server_close(&server); close(thread.pipe[1]); close(thread.pipe[0]); }