+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
#include <palacios/vmm_io.h>
#include <palacios/vmm_string.h>
#include <palacios/vmm.h>
#endif
-void init_vmm_io_map(vmm_io_map_t * io_map) {
+static int default_write(ushort_t port, void *src, uint_t length, void * priv_data);
+static int default_read(ushort_t port, void * dst, uint_t length, void * priv_data);
+
+
+void v3_init_vmm_io_map(struct guest_info * info) {
+ struct vmm_io_map * io_map = &(info->io_map);
io_map->num_ports = 0;
io_map->head = NULL;
}
-static int add_io_hook(vmm_io_map_t * io_map, vmm_io_hook_t * io_hook) {
+static int add_io_hook(struct vmm_io_map * io_map, struct vmm_io_hook * io_hook) {
if (!(io_map->head)) {
io_map->head = io_hook;
return 0;
} else {
- vmm_io_hook_t * tmp_hook = io_map->head;
+ struct vmm_io_hook * tmp_hook = io_map->head;
while ((tmp_hook->next) &&
(tmp_hook->next->port <= io_hook->port)) {
return -1;
}
-static int remove_io_hook(vmm_io_map_t * io_map, vmm_io_hook_t * io_hook) {
+static int remove_io_hook(struct vmm_io_map * io_map, struct vmm_io_hook * io_hook) {
if (io_map->head == io_hook) {
io_map->head = io_hook->next;
} else if (io_hook->prev) {
-/* FIX ME */
-static int default_write(ushort_t port, void *src, uint_t length, void * priv_data) {
- /*
-
- if (length == 1) {
- __asm__ __volatile__ (
- "outb %b0, %w1"
- :
- : "a" (*dst), "Nd" (port)
- );
- } else if (length == 2) {
- __asm__ __volatile__ (
- "outw %b0, %w1"
- :
- : "a" (*dst), "Nd" (port)
- );
- } else if (length == 4) {
- __asm__ __volatile__ (
- "outw %b0, %w1"
- :
- : "a" (*dst), "Nd" (port)
- );
- }
- */
- return 0;
-}
-
-static int default_read(ushort_t port, void * dst, uint_t length, void * priv_data)
-{
-
- /*
- uchar_t value;
-
- __asm__ __volatile__ (
- "inb %w1, %b0"
- : "=a" (value)
- : "Nd" (port)
- );
-
- return value;
- */
- return 0;
-}
-int v3_hook_io_port(vmm_io_map_t * io_map, uint_t port,
- int (*read)(ushort_t port, void * dst, uint_t length, void * priv_data),
- int (*write)(ushort_t port, void * src, uint_t length, void * priv_data),
- void * priv_data) {
- vmm_io_hook_t * io_hook = (vmm_io_hook_t *)V3_Malloc(sizeof(vmm_io_hook_t));
+int v3_hook_io_port(struct guest_info * info, uint_t port,
+ int (*read)(ushort_t port, void * dst, uint_t length, void * priv_data),
+ int (*write)(ushort_t port, void * src, uint_t length, void * priv_data),
+ void * priv_data) {
+ struct vmm_io_map * io_map = &(info->io_map);
+ struct vmm_io_hook * io_hook = (struct vmm_io_hook *)V3_Malloc(sizeof(struct vmm_io_hook));
io_hook->port = port;
return 0;
}
-int v3_unhook_io_port(vmm_io_map_t * io_map, uint_t port) {
- vmm_io_hook_t * hook = v3_get_io_hook(io_map, port);
+int v3_unhook_io_port(struct guest_info * info, uint_t port) {
+ struct vmm_io_map * io_map = &(info->io_map);
+ struct vmm_io_hook * hook = v3_get_io_hook(io_map, port);
if (hook == NULL) {
return -1;
}
-vmm_io_hook_t * v3_get_io_hook(vmm_io_map_t * io_map, uint_t port) {
- vmm_io_hook_t * tmp_hook;
+struct vmm_io_hook * v3_get_io_hook(struct vmm_io_map * io_map, uint_t port) {
+ struct vmm_io_hook * tmp_hook;
FOREACH_IO_HOOK(*io_map, tmp_hook) {
if (tmp_hook->port == port) {
return tmp_hook;
-void PrintDebugIOMap(vmm_io_map_t * io_map) {
- vmm_io_hook_t * iter = io_map->head;
+void v3_print_io_map(struct vmm_io_map * io_map) {
+ struct vmm_io_hook * iter = io_map->head;
PrintDebug("VMM IO Map (Entries=%d)\n", io_map->num_ports);
while (iter) {
- PrintDebug("IO Port: %hu (Read=%x) (Write=%x)\n", iter->port, iter->read, iter->write);
+ PrintDebug("IO Port: %hu (Read=%p) (Write=%p)\n",
+ iter->port,
+ (void *)(iter->read), (void *)(iter->write));
+ }
+}
+
+
+
+/*
+ * Write a byte to an I/O port.
+ */
+void v3_outb(ushort_t port, uchar_t value) {
+ __asm__ __volatile__ (
+ "outb %b0, %w1"
+ :
+ : "a" (value), "Nd" (port)
+ );
+}
+
+/*
+ * Read a byte from an I/O port.
+ */
+uchar_t v3_inb(ushort_t port) {
+ uchar_t value;
+
+ __asm__ __volatile__ (
+ "inb %w1, %b0"
+ : "=a" (value)
+ : "Nd" (port)
+ );
+
+ return value;
+}
+
+/*
+ * Write a word to an I/O port.
+ */
+void v3_outw(ushort_t port, ushort_t value) {
+ __asm__ __volatile__ (
+ "outw %w0, %w1"
+ :
+ : "a" (value), "Nd" (port)
+ );
+}
+
+/*
+ * Read a word from an I/O port.
+ */
+ushort_t v3_inw(ushort_t port) {
+ ushort_t value;
+
+ __asm__ __volatile__ (
+ "inw %w1, %w0"
+ : "=a" (value)
+ : "Nd" (port)
+ );
+
+ return value;
+}
+
+/*
+ * Write a double word to an I/O port.
+ */
+void v3_outdw(ushort_t port, uint_t value) {
+ __asm__ __volatile__ (
+ "outl %0, %1"
+ :
+ : "a" (value), "Nd" (port)
+ );
+}
+
+/*
+ * Read a double word from an I/O port.
+ */
+uint_t v3_indw(ushort_t port) {
+ uint_t value;
+
+ __asm__ __volatile__ (
+ "inl %1, %0"
+ : "=a" (value)
+ : "Nd" (port)
+ );
+
+ return value;
+}
+
+
+
+
+/* FIX ME */
+static int default_write(ushort_t port, void *src, uint_t length, void * priv_data) {
+ /*
+
+ if (length == 1) {
+ __asm__ __volatile__ (
+ "outb %b0, %w1"
+ :
+ : "a" (*dst), "Nd" (port)
+ );
+ } else if (length == 2) {
+ __asm__ __volatile__ (
+ "outw %b0, %w1"
+ :
+ : "a" (*dst), "Nd" (port)
+ );
+ } else if (length == 4) {
+ __asm__ __volatile__ (
+ "outw %b0, %w1"
+ :
+ : "a" (*dst), "Nd" (port)
+ );
}
+ */
+ return 0;
+}
+
+static int default_read(ushort_t port, void * dst, uint_t length, void * priv_data) {
+
+ /*
+ uchar_t value;
+
+ __asm__ __volatile__ (
+ "inb %w1, %b0"
+ : "=a" (value)
+ : "Nd" (port)
+ );
+
+ return value;
+ */
+
+ return 0;
}