2 * This file is part of the Palacios Virtual Machine Monitor developed
3 * by the V3VEE Project with funding from the United States National
4 * Science Foundation and the Department of Energy.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
11 * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
14 * Author: Jack Lange <jarusl@cs.northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
20 #include <palacios/vmm_io.h>
21 #include <palacios/vmm_string.h>
22 #include <palacios/vmm.h>
29 #define PrintDebug(fmt, args...)
33 void init_vmm_io_map(struct guest_info * info) {
34 struct vmm_io_map * io_map = &(info->io_map);
35 io_map->num_ports = 0;
43 static int add_io_hook(struct vmm_io_map * io_map, struct vmm_io_hook * io_hook) {
45 if (!(io_map->head)) {
46 io_map->head = io_hook;
47 io_map->num_ports = 1;
49 } else if (io_map->head->port > io_hook->port) {
50 io_hook->next = io_map->head;
52 io_map->head->prev = io_hook;
53 io_map->head = io_hook;
58 struct vmm_io_hook * tmp_hook = io_map->head;
60 while ((tmp_hook->next) &&
61 (tmp_hook->next->port <= io_hook->port)) {
62 tmp_hook = tmp_hook->next;
65 if (tmp_hook->port == io_hook->port) {
66 //tmp_hook->read = io_hook->read;
67 //tmp_hook->write = io_hook->write;
71 io_hook->prev = tmp_hook;
72 io_hook->next = tmp_hook->next;
75 tmp_hook->next->prev = io_hook;
78 tmp_hook->next = io_hook;
87 static int remove_io_hook(struct vmm_io_map * io_map, struct vmm_io_hook * io_hook) {
88 if (io_map->head == io_hook) {
89 io_map->head = io_hook->next;
90 } else if (io_hook->prev) {
91 io_hook->prev->next = io_hook->next;
94 // data corruption failure
98 io_hook->next->prev = io_hook->prev;
109 static int default_write(ushort_t port, void *src, uint_t length, void * priv_data) {
113 __asm__ __volatile__ (
116 : "a" (*dst), "Nd" (port)
118 } else if (length == 2) {
119 __asm__ __volatile__ (
122 : "a" (*dst), "Nd" (port)
124 } else if (length == 4) {
125 __asm__ __volatile__ (
128 : "a" (*dst), "Nd" (port)
135 static int default_read(ushort_t port, void * dst, uint_t length, void * priv_data)
141 __asm__ __volatile__ (
153 int v3_hook_io_port(struct guest_info * info, uint_t port,
154 int (*read)(ushort_t port, void * dst, uint_t length, void * priv_data),
155 int (*write)(ushort_t port, void * src, uint_t length, void * priv_data),
157 struct vmm_io_map * io_map = &(info->io_map);
158 struct vmm_io_hook * io_hook = (struct vmm_io_hook *)V3_Malloc(sizeof(struct vmm_io_hook));
160 io_hook->port = port;
163 io_hook->read = &default_read;
165 io_hook->read = read;
169 io_hook->write = &default_write;
171 io_hook->write = write;
174 io_hook->next = NULL;
175 io_hook->prev = NULL;
177 io_hook->priv_data = priv_data;
179 if (add_io_hook(io_map, io_hook) != 0) {
187 int v3_unhook_io_port(struct guest_info * info, uint_t port) {
188 struct vmm_io_map * io_map = &(info->io_map);
189 struct vmm_io_hook * hook = v3_get_io_hook(io_map, port);
195 remove_io_hook(io_map, hook);
200 struct vmm_io_hook * v3_get_io_hook(struct vmm_io_map * io_map, uint_t port) {
201 struct vmm_io_hook * tmp_hook;
202 FOREACH_IO_HOOK(*io_map, tmp_hook) {
203 if (tmp_hook->port == port) {
212 void PrintDebugIOMap(struct vmm_io_map * io_map) {
213 struct vmm_io_hook * iter = io_map->head;
215 PrintDebug("VMM IO Map (Entries=%d)\n", io_map->num_ports);
218 PrintDebug("IO Port: %hu (Read=%x) (Write=%x)\n", iter->port, iter->read, iter->write);