3 * This file is part of the Palacios Virtual Machine Monitor developed
4 * by the V3VEE Project with funding from the United States National
5 * Science Foundation and the Department of Energy.
7 * The V3VEE Project is a joint project between Northwestern University
8 * and the University of New Mexico. You can find out more at
11 * Copyright (c) 2012, Jack Lange <jarusl@cs.pitt.edu>
12 * Copyright (c) 2012, The V3VEE Project <http://www.v3vee.org>
13 * All rights reserved.
15 * Author: Jack Lange <jarusl@cs.pitt.edu>
17 * This is free software. You are permitted to use,
18 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
21 #include <palacios/vmm.h>
22 #include <palacios/vmm_extensions.h>
23 #include <palacios/vmm_io.h>
24 #include <palacios/vmm_cpuid.h>
25 #include <palacios/vm_guest.h>
28 #define VMWARE_CPUID_LEAF 0x40000000
29 #define VMWARE_MAGIC 0x564D5868
30 #define VMWARE_IO_PORT 0x5658
32 #define VMWARE_IO_VERSION 10
33 #define VMWARE_IO_GETHZ 45
36 static int io_read(struct guest_info * core, uint16_t port, void * dst, uint_t length, void * priv_data) {
37 uint64_t cpu_hz = V3_CPU_KHZ() * 1000;
38 uint32_t magic = (uint32_t)(core->vm_regs.rax);
39 uint32_t cmd = (uint32_t)(core->vm_regs.rcx);
41 PrintError(core->vm_info, core, "VMWARE IO READ of size %d (command=%d)\n", length, cmd);
44 if (magic != VMWARE_MAGIC) {
45 PrintError(core->vm_info, core, "Invalid VMWARE MAgic number in Persona interface, ignoring for now\n");
49 if (cmd == VMWARE_IO_GETHZ) {
50 // EAX Takes low bytes
51 // EBX takes high bytes
52 core->vm_regs.rax = cpu_hz & 0x00000000ffffffffLL;
53 core->vm_regs.rbx = (cpu_hz >> 32) & 0x00000000ffffffffLL;
55 PrintError(core->vm_info, core, "Unhandled VMWARE IO operation\n");
63 static int io_write(struct guest_info * core, uint16_t port, void * src, uint_t length, void * priv_data) {
65 PrintError(core->vm_info, core, "VMWARE IO PORT WRITE\n");
70 static int vmware_cpuid_handler(struct guest_info * core, uint32_t cpuid,
71 uint32_t * eax, uint32_t * ebx,
72 uint32_t * ecx, uint32_t * edx,
78 // Set VMWARE Vendor string in EBX,ECX,EDX
79 memcpy(ebx, "VMwa", 4);
80 memcpy(ecx, "reVM", 4);
81 memcpy(edx, "ware", 4);
88 static int vmware_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg, void ** priv_data) {
90 V3_Print(vm, VCORE_NONE, "Using VMWARE virtualization persona\n");
93 v3_cpuid_add_fields(vm, 0x00000001,
96 0x80000000, 0x80000000,
101 v3_hook_io_port(vm, VMWARE_IO_PORT,
105 v3_hook_cpuid(vm, VMWARE_CPUID_LEAF,
106 vmware_cpuid_handler, NULL);
110 // set CPUID hypervisor enabled
122 static struct v3_extension_impl vmware_impl = {
123 .name = "VMWARE_IFACE",
134 register_extension(&vmware_impl);