1 #include <palacios/vmm_io.h>
2 #include <palacios/vmm_string.h>
3 #include <palacios/vmm.h>
5 extern struct vmm_os_hooks * os_hooks;
10 #define PrintDebug(fmt, args...)
14 void init_vmm_io_map(vmm_io_map_t * io_map) {
15 io_map->num_ports = 0;
21 int add_io_hook(vmm_io_map_t * io_map, vmm_io_hook_t * io_hook) {
23 if (!(io_map->head)) {
24 io_map->head = io_hook;
25 io_map->num_ports = 1;
27 } else if (io_map->head->port > io_hook->port) {
28 io_hook->next = io_map->head;
30 io_map->head->prev = io_hook;
31 io_map->head = io_hook;
36 vmm_io_hook_t * tmp_hook = io_map->head;
38 while ((tmp_hook->next) &&
39 (tmp_hook->next->port <= io_hook->port)) {
40 tmp_hook = tmp_hook->next;
43 if (tmp_hook->port == io_hook->port) {
44 //tmp_hook->read = io_hook->read;
45 //tmp_hook->write = io_hook->write;
49 io_hook->prev = tmp_hook;
50 io_hook->next = tmp_hook->next;
53 tmp_hook->next->prev = io_hook;
56 tmp_hook->next = io_hook;
65 int remove_io_hook(vmm_io_map_t * io_map, vmm_io_hook_t * io_hook) {
66 if (io_map->head == io_hook) {
67 io_map->head = io_hook->next;
68 } else if (io_hook->prev) {
69 io_hook->prev->next = io_hook->next;
72 // data corruption failure
76 io_hook->next->prev = io_hook->prev;
87 static int default_write(ushort_t port, void *src, uint_t length, void * priv_data) {
91 __asm__ __volatile__ (
94 : "a" (*dst), "Nd" (port)
96 } else if (length == 2) {
97 __asm__ __volatile__ (
100 : "a" (*dst), "Nd" (port)
102 } else if (length == 4) {
103 __asm__ __volatile__ (
106 : "a" (*dst), "Nd" (port)
113 static int default_read(ushort_t port, void * dst, uint_t length, void * priv_data)
119 __asm__ __volatile__ (
131 int hook_io_port(vmm_io_map_t * io_map, uint_t port,
132 int (*read)(ushort_t port, void * dst, uint_t length, void * priv_data),
133 int (*write)(ushort_t port, void * src, uint_t length, void * priv_data),
135 vmm_io_hook_t * io_hook = os_hooks->malloc(sizeof(vmm_io_hook_t));
137 io_hook->port = port;
140 io_hook->read = &default_read;
142 io_hook->read = read;
146 io_hook->write = &default_write;
148 io_hook->write = write;
151 io_hook->next = NULL;
152 io_hook->prev = NULL;
154 io_hook->priv_data = priv_data;
156 if (add_io_hook(io_map, io_hook) != 0) {
164 int unhook_io_port(vmm_io_map_t * io_map, uint_t port) {
165 vmm_io_hook_t * hook = get_io_hook(io_map, port);
171 remove_io_hook(io_map, hook);
176 vmm_io_hook_t * get_io_hook(vmm_io_map_t * io_map, uint_t port) {
177 vmm_io_hook_t * tmp_hook;
178 FOREACH_IO_HOOK(*io_map, tmp_hook) {
179 if (tmp_hook->port == port) {
188 void PrintDebugIOMap(vmm_io_map_t * io_map) {
189 vmm_io_hook_t * iter = io_map->head;
191 PrintDebug("VMM IO Map (Entries=%d)\n", io_map->num_ports);
194 PrintDebug("IO Port: %hu (Read=%x) (Write=%x)\n", iter->port, iter->read, iter->write);