#include <palacios/vmm_dev_mgr.h>
#include <palacios/vm_guest_mem.h>
-#ifdef CONFIG_HOST_DEVICE
+#ifdef V3_CONFIG_HOST_DEVICE
#include <interfaces/vmm_host_dev.h>
#endif
-#ifndef CONFIG_DEBUG_GENERIC
+#ifndef V3_CONFIG_DEBUG_GENERIC
#undef PrintDebug
#define PrintDebug(fmt, args...)
#endif
struct generic_internal {
enum {GENERIC_PHYSICAL, GENERIC_HOST} forward_type;
-#ifdef CONFIG_HOST_DEVICE
+#ifdef V3_CONFIG_HOST_DEVICE
v3_host_dev_t host_dev;
#endif
struct vm_device *dev; // me
}
return length;
break;
-#ifdef CONFIG_HOST_DEVICE
+#ifdef V3_CONFIG_HOST_DEVICE
case GENERIC_HOST:
if (state->host_dev) {
return v3_host_dev_write_io(state->host_dev,port,src,length);
uint_t i;
int rc;
-#ifdef CONFIG_DEBUG_GENERIC
+#ifdef V3_CONFIG_DEBUG_GENERIC
struct generic_internal *state = (struct generic_internal *) priv_data;
#endif
}
return length;
break;
-#ifdef CONFIG_HOST_DEVICE
+#ifdef V3_CONFIG_HOST_DEVICE
case GENERIC_HOST:
if (state->host_dev) {
return v3_host_dev_read_io(state->host_dev,port,dst,length);
uint_t i;
int rc;
-#ifdef CONFIG_DEBUG_GENERIC
+#ifdef V3_CONFIG_DEBUG_GENERIC
struct generic_internal *state = (struct generic_internal *) priv_data;
#endif
static int generic_read_port_print_and_ignore(struct guest_info * core, uint16_t port, void * src,
uint_t length, void * priv_data) {
-#ifdef CONFIG_DEBUG_GENERIC
+#ifdef V3_CONFIG_DEBUG_GENERIC
struct generic_internal *state = (struct generic_internal *) priv_data;
#endif
uint_t length, void * priv_data) {
int i;
-#ifdef CONFIG_DEBUG_GENERIC
+#ifdef V3_CONFIG_DEBUG_GENERIC
struct generic_internal *state = (struct generic_internal *) priv_data;
#endif
memcpy(V3_VAddr((void*)gpa),src,len);
return len;
break;
-#ifdef CONFIG_HOST_DEVICE
+#ifdef V3_CONFIG_HOST_DEVICE
case GENERIC_HOST:
if (state->host_dev) {
return v3_host_dev_write_mem(state->host_dev,gpa,src,len);
uint_t len,
void * priv)
{
-#ifdef CONFIG_DEBUG_GENERIC
+#ifdef V3_CONFIG_DEBUG_GENERIC
struct vm_device *dev = (struct vm_device *) priv;
struct generic_internal *state = (struct generic_internal *) dev->private_data;
#endif
uint_t len,
void * priv)
{
-#ifdef CONFIG_DEBUG_GENERIC
+#ifdef V3_CONFIG_DEBUG_GENERIC
struct vm_device *dev = (struct vm_device *) priv;
struct generic_internal *state = (struct generic_internal *) dev->private_data;
#endif
memcpy(dst,V3_VAddr((void*)gpa),len);
return len;
break;
-#ifdef CONFIG_HOST_DEVICE
+#ifdef V3_CONFIG_HOST_DEVICE
case GENERIC_HOST:
if (state->host_dev) {
return v3_host_dev_read_mem(state->host_dev,gpa,dst,len);
uint_t len,
void * priv)
{
-#ifdef CONFIG_DEBUG_GENERIC
+#ifdef V3_CONFIG_DEBUG_GENERIC
struct vm_device *dev = (struct vm_device *) priv;
struct generic_internal *state = (struct generic_internal *) dev->private_data;
#endif
uint_t len,
void * priv)
{
-#ifdef CONFIG_DEBUG_GENERIC
+#ifdef V3_CONFIG_DEBUG_GENERIC
struct vm_device *dev = (struct vm_device *) priv;
struct generic_internal *state = (struct generic_internal *) dev->private_data;
#endif
PrintDebug("generic (%s): deinit_device\n", state->name);
-#ifdef CONFIG_HOST_DEVICE
+#ifdef V3_CONFIG_HOST_DEVICE
if (state->host_dev) {
v3_host_dev_close(state->host_dev);
state->host_dev=0;
return -1;
}
break;
-
+
case GENERIC_IGNORE:
if (v3_hook_full_mem(dev->vm, V3_MEM_CORE_ANY, start, end+1,
&generic_read_mem_ignore,
PrintError("generic (%s): huh?\n",state->name);
break;
}
+
+ return 0;
+}
+
+
+#if 1
+
+//This is a hack for host device testing and will be removed
+
+static int osdebug_hcall(struct guest_info *core, uint_t hcall_id, void * priv_data)
+{
+ struct generic_internal * state = (struct generic_internal *)priv_data;
+
+ int msg_len = core->vm_regs.rcx;
+ addr_t msg_gpa = core->vm_regs.rbx;
+ int buf_is_va = core->vm_regs.rdx;
+ int i;
+ uint8_t c;
+
+ PrintDebug("generic (%s): handling hypercall (len=%d) as sequence of port writes\n",
+ state->name, msg_len);
+
+
+ for (i=0;i<msg_len;i++) {
+ if (buf_is_va == 1) {
+ if (v3_read_gva_memory(core, msg_gpa+i, 1, &c) != 1) {
+ PrintError("generic (%s): could not read debug message\n",state->name);
+ return -1;
+ }
+ } else {
+ if (v3_read_gpa_memory(core, msg_gpa+i, 1, &c) != 1) {
+ PrintError("generic (%s): Could not read debug message\n",state->name);
+ return -1;
+ }
+ }
+ if (generic_write_port_print_and_passthrough(core,0xc0c0,&c,1,priv_data)!=1) {
+ PrintError("generic (%s): write port passthrough failed\n",state->name);
+ return -1;
+ }
+ }
return 0;
}
+#endif
/*
struct generic_internal * state = NULL;
char * dev_id = v3_cfg_val(cfg, "ID");
char * forward = v3_cfg_val(cfg, "forward");
-#ifdef CONFIG_HOST_DEVICE
+#ifdef V3_CONFIG_HOST_DEVICE
char * host_dev = v3_cfg_val(cfg, "hostdev");
#endif
v3_cfg_tree_t * port_cfg = v3_cfg_subtree(cfg, "ports");
if (!strcasecmp(forward,"physical_device")) {
state->forward_type=GENERIC_PHYSICAL;
} else if (!strcasecmp(forward,"host_device")) {
-#ifdef CONFIG_HOST_DEVICE
+#ifdef V3_CONFIG_HOST_DEVICE
state->forward_type=GENERIC_HOST;
#else
PrintError("generic (%s): cannot configure host device since host device support is not built in\n", state->name);
state->dev=dev;
-#ifdef CONFIG_HOST_DEVICE
+#ifdef V3_CONFIG_HOST_DEVICE
if (state->forward_type==GENERIC_HOST) {
if (!host_dev) {
PrintError("generic (%s): host forwarding requested, but no host device given\n", state->name);
v3_remove_device(dev);
return -1;
} else {
- state->host_dev = v3_host_dev_open(host_dev,V3_BUS_CLASS_DIRECT,dev);
+ state->host_dev = v3_host_dev_open(host_dev,V3_BUS_CLASS_DIRECT,dev,vm);
if (!(state->host_dev)) {
PrintError("generic (%s): unable to open host device \"%s\"\n", state->name,host_dev);
v3_remove_device(dev);
mem_cfg = v3_cfg_next_branch(port_cfg);
}
+
+#if 1
+ // hack for os debug testing
+ if (strcasecmp(state->name,"os debug")==0) {
+ PrintDebug("generic (%s): adding hypercall for os debug device\n", state->name);
+ v3_register_hypercall(vm,0xc0c0,osdebug_hcall,state);
+ }
+#endif
PrintDebug("generic (%s): initialization complete\n", state->name);