1 /* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
2 /* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
4 #include <palacios/vmm_io.h>
5 #include <palacios/vmm_string.h>
6 #include <palacios/vmm.h>
13 #define PrintDebug(fmt, args...)
17 void init_vmm_io_map(struct guest_info * info) {
18 struct vmm_io_map * io_map = &(info->io_map);
19 io_map->num_ports = 0;
27 static int add_io_hook(struct vmm_io_map * io_map, struct vmm_io_hook * io_hook) {
29 if (!(io_map->head)) {
30 io_map->head = io_hook;
31 io_map->num_ports = 1;
33 } else if (io_map->head->port > io_hook->port) {
34 io_hook->next = io_map->head;
36 io_map->head->prev = io_hook;
37 io_map->head = io_hook;
42 struct vmm_io_hook * tmp_hook = io_map->head;
44 while ((tmp_hook->next) &&
45 (tmp_hook->next->port <= io_hook->port)) {
46 tmp_hook = tmp_hook->next;
49 if (tmp_hook->port == io_hook->port) {
50 //tmp_hook->read = io_hook->read;
51 //tmp_hook->write = io_hook->write;
55 io_hook->prev = tmp_hook;
56 io_hook->next = tmp_hook->next;
59 tmp_hook->next->prev = io_hook;
62 tmp_hook->next = io_hook;
71 static int remove_io_hook(struct vmm_io_map * io_map, struct vmm_io_hook * io_hook) {
72 if (io_map->head == io_hook) {
73 io_map->head = io_hook->next;
74 } else if (io_hook->prev) {
75 io_hook->prev->next = io_hook->next;
78 // data corruption failure
82 io_hook->next->prev = io_hook->prev;
93 static int default_write(ushort_t port, void *src, uint_t length, void * priv_data) {
97 __asm__ __volatile__ (
100 : "a" (*dst), "Nd" (port)
102 } else if (length == 2) {
103 __asm__ __volatile__ (
106 : "a" (*dst), "Nd" (port)
108 } else if (length == 4) {
109 __asm__ __volatile__ (
112 : "a" (*dst), "Nd" (port)
119 static int default_read(ushort_t port, void * dst, uint_t length, void * priv_data)
125 __asm__ __volatile__ (
137 int v3_hook_io_port(struct guest_info * info, uint_t port,
138 int (*read)(ushort_t port, void * dst, uint_t length, void * priv_data),
139 int (*write)(ushort_t port, void * src, uint_t length, void * priv_data),
141 struct vmm_io_map * io_map = &(info->io_map);
142 struct vmm_io_hook * io_hook = (struct vmm_io_hook *)V3_Malloc(sizeof(struct vmm_io_hook));
144 io_hook->port = port;
147 io_hook->read = &default_read;
149 io_hook->read = read;
153 io_hook->write = &default_write;
155 io_hook->write = write;
158 io_hook->next = NULL;
159 io_hook->prev = NULL;
161 io_hook->priv_data = priv_data;
163 if (add_io_hook(io_map, io_hook) != 0) {
171 int v3_unhook_io_port(struct guest_info * info, uint_t port) {
172 struct vmm_io_map * io_map = &(info->io_map);
173 struct vmm_io_hook * hook = v3_get_io_hook(io_map, port);
179 remove_io_hook(io_map, hook);
184 struct vmm_io_hook * v3_get_io_hook(struct vmm_io_map * io_map, uint_t port) {
185 struct vmm_io_hook * tmp_hook;
186 FOREACH_IO_HOOK(*io_map, tmp_hook) {
187 if (tmp_hook->port == port) {
196 void PrintDebugIOMap(struct vmm_io_map * io_map) {
197 struct vmm_io_hook * iter = io_map->head;
199 PrintDebug("VMM IO Map (Entries=%d)\n", io_map->num_ports);
202 PrintDebug("IO Port: %hu (Read=%x) (Write=%x)\n", iter->port, iter->read, iter->write);