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;
11 void init_vmm_io_map(vmm_io_map_t * io_map) {
12 io_map->num_ports = 0;
18 int add_io_hook(vmm_io_map_t * io_map, vmm_io_hook_t * io_hook) {
20 if (!(io_map->head)) {
21 io_map->head = io_hook;
22 io_map->num_ports = 1;
24 } else if (io_map->head->port > io_hook->port) {
25 io_hook->next = io_map->head;
27 io_map->head->prev = io_hook;
28 io_map->head = io_hook;
33 vmm_io_hook_t * tmp_hook = io_map->head;
35 while ((tmp_hook->next) &&
36 (tmp_hook->next->port <= io_hook->port)) {
37 tmp_hook = tmp_hook->next;
40 if (tmp_hook->port == io_hook->port) {
41 //tmp_hook->read = io_hook->read;
42 //tmp_hook->write = io_hook->write;
46 io_hook->prev = tmp_hook;
47 io_hook->next = tmp_hook->next;
50 tmp_hook->next->prev = io_hook;
53 tmp_hook->next = io_hook;
62 int remove_io_hook(vmm_io_map_t * io_map, vmm_io_hook_t * io_hook) {
63 if (io_map->head == io_hook) {
64 io_map->head = io_hook->next;
65 } else if (io_hook->prev) {
66 io_hook->prev->next = io_hook->next;
69 // data corruption failure
73 io_hook->next->prev = io_hook->prev;
84 static int default_write(ushort_t port, void *src, uint_t length, void * priv_data) {
88 __asm__ __volatile__ (
91 : "a" (*dst), "Nd" (port)
93 } else if (length == 2) {
94 __asm__ __volatile__ (
97 : "a" (*dst), "Nd" (port)
99 } else if (length == 4) {
100 __asm__ __volatile__ (
103 : "a" (*dst), "Nd" (port)
110 static int default_read(ushort_t port, void * dst, uint_t length, void * priv_data)
116 __asm__ __volatile__ (
128 int hook_io_port(vmm_io_map_t * io_map, uint_t port,
129 int (*read)(ushort_t port, void * dst, uint_t length, void * priv_data),
130 int (*write)(ushort_t port, void * src, uint_t length, void * priv_data),
132 vmm_io_hook_t * io_hook = os_hooks->malloc(sizeof(vmm_io_hook_t));
134 io_hook->port = port;
137 io_hook->read = &default_read;
139 io_hook->read = read;
143 io_hook->write = &default_write;
145 io_hook->write = write;
148 io_hook->next = NULL;
149 io_hook->prev = NULL;
151 io_hook->priv_data = priv_data;
153 if (add_io_hook(io_map, io_hook) != 0) {
161 int unhook_io_port(vmm_io_map_t * io_map, uint_t port) {
162 vmm_io_hook_t * hook = get_io_hook(io_map, port);
168 remove_io_hook(io_map, hook);
173 vmm_io_hook_t * get_io_hook(vmm_io_map_t * io_map, uint_t port) {
174 vmm_io_hook_t * tmp_hook;
175 FOREACH_IO_HOOK(*io_map, tmp_hook) {
176 if (tmp_hook->port == port) {
185 void PrintDebugIOMap(vmm_io_map_t * io_map) {
186 vmm_io_hook_t * iter = io_map->head;
188 PrintDebug("VMM IO Map (Entries=%d)\n", io_map->num_ports);
191 PrintDebug("IO Port: %hu (Read=%x) (Write=%x)\n", iter->port, iter->read, iter->write);