Пример #1
0
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;
}
Пример #2
0
static void test_ivshmem_server(bool msi)
{
    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, msi);
    s1 = &state1;
    setup_vm_with_server(&state2, nvectors, msi);
    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 */
    global_qtest = s1->qs->qts;
    if (msi) {
        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 */
    if (msi) {
        ret = qpci_msix_pending(s1->dev, 0);
        g_assert_cmpuint(ret, ==, 0);
    } else {
Пример #3
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];
//	}
}
Пример #4
0
frame_t frame(tmp_label_t name, list_t formals)
{
    frame_t p = checked_malloc(sizeof(*p));
    list_t formal = formals, q = NULL;
    int i = 0;

    p->name = name;
    p->locals = NULL;
    p->local_count = 0;
    for (; formal; formal = formal->next, i++)
    {
        fr_access_t access;
        if (formal->b || i >= K)
            access = in_frame(i * FR_WORD_SIZE);
        else
            access = in_reg(temp());
        if (q)
        {
            q->next = list(access, NULL);
            q = q->next;
        }
        else
            p->formals = q = list(access, NULL);
    }
    return p;
}
Пример #5
0
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);
}
Пример #6
0
fr_access_t fr_alloc_local(frame_t fr, bool escape)
{
    fr_access_t access;

    if (escape)
    {
        fr->local_count++;
        /* -2 for the the return address and frame pointer. */
        access = in_frame(FR_WORD_SIZE * (-2 - fr->local_count));
    }
    else
        access = in_reg(temp());
    if (fr->locals)
    {
        list_t p = fr->locals;
        while (p->next)
            p = p->next;
        p->next = list(access, NULL);
    }
    else
        fr->locals = list(access, NULL);
    return access;
}
Пример #7
0
void bios_create_smap()
{
	rm_ctx     ctx;
	e820map    map;
	e820entry *ent, tmp;
	u32        base, size;
	int        i;

	/* setup initial context */
	btab->p_set_ctx(0, &ctx);
	/* get system memory map */
	map.n_map = 0; base = bdat->bd_base; size = bdat->bd_size;
	do
	{
		ctx.eax = 0x0000E820;
		ctx.edx = 0x534D4150;
		ctx.ecx = sizeof(e820entry);
		ctx.es  = rm_seg(&map.map[map.n_map]);
		ctx.di  = rm_off(&map.map[map.n_map]);

		if ( (btab->p_bios_call(0x15, &ctx) == 0) || (ctx.eax != 0x534D4150) ) {
			break;
		}
	} while ( (++map.n_map < E820MAX) && (ctx.ebx != 0) );

	/* append my real mode block to second region */
	if ( (map.n_map >= 2) && (map.map[0].type == E820_RAM) && 
		 (map.map[1].type == E820_RESERVED) && (map.map[0].base == 0) &&
		 (map.map[1].base == map.map[0].size) &&
		 (base + size == map.map[0].size) )
	{
		map.map[0].size  = base;
		map.map[1].base  = map.map[0].size;
		map.map[1].size += size;		
	}
	
	/* build new memory map without my regions */
	for (i = 0; i < map.n_map; i++)
	{
		ent = &map.map[i];

		if ( (ent->type == E820_RAM) && 
			 (in_reg(base, ent->base, ent->size) != 0) )
		{
			tmp.base = ent->base;
			tmp.size = base - ent->base;
			tmp.type = ent->type;
			add_smap(&tmp);

			tmp.base = base;
			tmp.size = size;
			tmp.type = E820_RESERVED;
			add_smap(&tmp);

			if (ent->base + ent->size > base + size) 
			{
				tmp.base = base + size;
				tmp.size = ent->base + ent->size - tmp.base;
				tmp.type = ent->type;
				add_smap(&tmp);
			}
		} else {
			add_smap(ent);
		}
	}
}
Пример #8
0
static int pe2mod(wchar_t *in, wchar_t *out) 
{
	IMAGE_DOS_HEADER     *d_head;
	IMAGE_NT_HEADERS     *n_head;
	IMAGE_SECTION_HEADER *t_sect;
	boot_mod             *b_mod = NULL;
	HMODULE               image = NULL;
	u32                  *reloc = NULL;
	int                   resl  = 1;
	u32                   r_num, offs;
	HANDLE                h_out;
	u32                   i, found;
	u32                   code_off;
	u32                   bytes, n;
	u8                   *s_data;
	u32                   s_size;

	do
	{
		if ( (image = LoadLibraryEx(in, NULL, DONT_RESOLVE_DLL_REFERENCES)) == NULL ) {
			break;
		}
		d_head = pv(dSZ(image) & ~(PAGE_SIZE - 1));
		n_head = addof(d_head, d_head->e_lfanew);
		t_sect = IMAGE_FIRST_SECTION(n_head);
		found  = 0;

		/* find '.text' section */
		for (i = 0; i < n_head->FileHeader.NumberOfSections; i++, t_sect++) {
			if (_stricmp(t_sect->Name, ".text") == 0) {	found = 1; break; }
		}
		if (found == 0) {
			wprintf(L"Invalid PE image %s, section '.text' is not found\n", in); 
			break;
		}
		if ( (reloc = calloc(1, n_head->OptionalHeader.SizeOfImage)) == NULL ) {
			break;
		}
		if ( (b_mod = calloc(1, n_head->OptionalHeader.SizeOfImage)) == NULL ) {
			break;
		}
		if (r_num = pe_save_relocs(d_head, reloc)) 
		{
			/* save needed relocs */
			for (i = 0, n = 0; i < r_num; i++) 
			{
				if (in_reg(reloc[i], t_sect->VirtualAddress, t_sect->Misc.VirtualSize) != 0) {
					b_mod->relocs[n++] = reloc[i]; 
				}
			}
			b_mod->n_rels = n;
			code_off = _align(sizeof(boot_mod) + n * sizeof(u32), 16);			
		} else {
			code_off = _align(sizeof(boot_mod), 16);
		}
		s_data = addof(d_head, t_sect->VirtualAddress);
		s_size = t_sect->SizeOfRawData;

		/* find minimum section RAW size */
		for (i = t_sect->SizeOfRawData - 1; i != 0; i--, s_size--) {
			if (s_data[i] != 0) break;
		}
		b_mod->mod_sign  = 'DCBM';
		b_mod->raw_size  = s_size + code_off;
		b_mod->virt_size = t_sect->Misc.VirtualSize + code_off;
		b_mod->entry_rva = n_head->OptionalHeader.AddressOfEntryPoint - 
			t_sect->VirtualAddress + code_off;

		memcpy(addof(b_mod, code_off), s_data, s_size);

		/* rebase image and fix relocs */
		for (i = 0; i < b_mod->n_rels; i++)
		{
			offs = b_mod->relocs[i] - t_sect->VirtualAddress + code_off;			
			p32(addof(b_mod, offs))[0] -= n_head->OptionalHeader.ImageBase + 
				t_sect->VirtualAddress - code_off;
			b_mod->relocs[i] = offs;
		}
		h_out = CreateFile(
			out, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);

		if (h_out != INVALID_HANDLE_VALUE) 
		{
			if (WriteFile(h_out, b_mod, b_mod->raw_size, &bytes, NULL) != 0) 
			{
				wprintf(L"Boot module OK (Virtual size: %d, Raw size: %d, EP: %d)\n", 
					b_mod->virt_size, b_mod->raw_size, b_mod->entry_rva);
				resl = 0;
			}
			CloseHandle(h_out);
		} else {
			wprintf(L"Can not write to %s", out);
		}
	} while (0);

	if (reloc != NULL) { free(reloc); }
	if (b_mod != NULL) { free(b_mod); }
	if (image != NULL) { FreeLibrary(image); }

	return resl;
}
Пример #9
0
static int find_and_map(void)
{
	int err;
	pci_module_hooks *pci;
	pci_info pinfo;
	aspace_id kai = vm_get_kernel_aspace_id();
	int i;
	bool foundit;

	if(module_get(PCI_BUS_MODULE_NAME, 0, (void **)&pci) < 0) {
		dprintf("vmware: no pci bus found..\n");
		err = ERR_NOT_FOUND;
		goto error0;
	}

	foundit = false;
	for(i = 0; pci->get_nth_pci_info(i, &pinfo) >= NO_ERROR; i++) {
		dprintf("vmware: looking at 0x%x:0x%x\n", pinfo.vendor_id, pinfo.device_id);
		if(pinfo.vendor_id == PCI_VENDOR_ID_VMWARE &&
			(pinfo.device_id == PCI_DEVICE_ID_VMWARE_SVGA2 || pinfo.device_id == PCI_DEVICE_ID_VMWARE_SVGA)) {
			foundit = true;
			break;
		}
	}
	if(!foundit) {
		dprintf("vmware: didn't find device on pci bus\n");
		err = ERR_NOT_FOUND;
		goto error0;
	}

	switch(pinfo.device_id) {
		case PCI_DEVICE_ID_VMWARE_SVGA:
			dprintf("vmware SVGA device detected at pci %d:%d:%d\n", pinfo.bus, pinfo.device, pinfo.function);
			vcons.index_port = SVGA_LEGACY_BASE_PORT + SVGA_INDEX_PORT * 4;
			vcons.value_port = SVGA_LEGACY_BASE_PORT + SVGA_VALUE_PORT * 4;
			break;
		case PCI_DEVICE_ID_VMWARE_SVGA2:
			dprintf("vmware SVGA2 device detected at pci %d:%d:%d\n", pinfo.bus, pinfo.device, pinfo.function);
			vcons.index_port = pinfo.u.h0.base_registers[0] + SVGA_INDEX_PORT;
			vcons.value_port = pinfo.u.h0.base_registers[0] + SVGA_VALUE_PORT;
			break;
	}
	vcons.fb_phys_base = pinfo.u.h0.base_registers[1];
	vcons.fb_size = MIN(pinfo.u.h0.base_register_sizes[1], SVGA_FB_MAX_SIZE);
	vcons.fifo_phys_base = pinfo.u.h0.base_registers[2];
	vcons.fifo_size = MIN(pinfo.u.h0.base_register_sizes[2], SVGA_MEM_SIZE);

	dprintf("vmware: index port 0x%x, value port 0x%x\n", vcons.index_port, vcons.value_port);
	dprintf("vmware: phys base 0x%x, size 0x%X\n", vcons.fb_phys_base, vcons.fb_size);
	dprintf("vmware: fifo phys base 0x%x, fifo size 0x%X\n", vcons.fifo_phys_base, vcons.fifo_size);

	vcons.fb_region = vm_map_physical_memory(kai, "vmw:fb", (void **)&vcons.fb_base, REGION_ADDR_ANY_ADDRESS, vcons.fb_size, LOCK_KERNEL | LOCK_RW, vcons.fb_phys_base);
	if (vcons.fb_region < 0)
	{
		err = vcons.fb_region;
		dprintf("Error mapping frame buffer: %x\n", err);
		goto error0;
	}
	vcons.fifo_region = vm_map_physical_memory(kai, "vmw:fifo", (void **)&vcons.fifo_base, REGION_ADDR_ANY_ADDRESS, vcons.fifo_size, LOCK_KERNEL | LOCK_RW, vcons.fifo_phys_base);
	if (vcons.fifo_region < 0)
	{
		err = vcons.fifo_region;
		dprintf("Error mapping vmw::fifo: %x\n", err);
		goto error1;
	}

	// XXX this makes the emulation unhappy (crashes vmware)
//	out_reg(SVGA_REG_ID, SVGA_ID_2);
//	vcons.svga_id = in_reg(SVGA_REG_ID);
//	dprintf("vmware: svga version %d\n", vcons.svga_id);
	
	vcons.bits_per_pixel = in_reg(SVGA_REG_BITS_PER_PIXEL);
	dprintf("vmware: bpp %d\n", vcons.bits_per_pixel);

	err = NO_ERROR;
	goto error0;

	// unmap vcons.fifo_region
	vm_delete_region(kai, vcons.fifo_region);
error1:
	// unmap vcons.fb_region
	vm_delete_region(kai, vcons.fb_region);
error0:
	return err;
}
Пример #10
0
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]);
}