1 #include <palacios/vmm_io.h>
2 #include <palacios/vmm_string.h>
3 #include <palacios/vmm.h>
10 #define PrintDebug(fmt, args...)
14 void init_vmm_io_map(vmm_io_map_t * io_map) {
15 io_map->num_ports = 0;
23 static int add_io_hook(vmm_io_map_t * io_map, vmm_io_hook_t * io_hook) {
25 if (!(io_map->head)) {
26 io_map->head = io_hook;
27 io_map->num_ports = 1;
29 } else if (io_map->head->port > io_hook->port) {
30 io_hook->next = io_map->head;
32 io_map->head->prev = io_hook;
33 io_map->head = io_hook;
38 vmm_io_hook_t * tmp_hook = io_map->head;
40 while ((tmp_hook->next) &&
41 (tmp_hook->next->port <= io_hook->port)) {
42 tmp_hook = tmp_hook->next;
45 if (tmp_hook->port == io_hook->port) {
46 //tmp_hook->read = io_hook->read;
47 //tmp_hook->write = io_hook->write;
51 io_hook->prev = tmp_hook;
52 io_hook->next = tmp_hook->next;
55 tmp_hook->next->prev = io_hook;
58 tmp_hook->next = io_hook;
67 static int remove_io_hook(vmm_io_map_t * io_map, vmm_io_hook_t * io_hook) {
68 if (io_map->head == io_hook) {
69 io_map->head = io_hook->next;
70 } else if (io_hook->prev) {
71 io_hook->prev->next = io_hook->next;
74 // data corruption failure
78 io_hook->next->prev = io_hook->prev;
89 static int default_write(ushort_t port, void *src, uint_t length, void * priv_data) {
93 __asm__ __volatile__ (
96 : "a" (*dst), "Nd" (port)
98 } else if (length == 2) {
99 __asm__ __volatile__ (
102 : "a" (*dst), "Nd" (port)
104 } else if (length == 4) {
105 __asm__ __volatile__ (
108 : "a" (*dst), "Nd" (port)
115 static int default_read(ushort_t port, void * dst, uint_t length, void * priv_data)
121 __asm__ __volatile__ (
133 int v3_hook_io_port(vmm_io_map_t * io_map, uint_t port,
134 int (*read)(ushort_t port, void * dst, uint_t length, void * priv_data),
135 int (*write)(ushort_t port, void * src, uint_t length, void * priv_data),
137 vmm_io_hook_t * io_hook = (vmm_io_hook_t *)V3_Malloc(sizeof(vmm_io_hook_t));
139 io_hook->port = port;
142 io_hook->read = &default_read;
144 io_hook->read = read;
148 io_hook->write = &default_write;
150 io_hook->write = write;
153 io_hook->next = NULL;
154 io_hook->prev = NULL;
156 io_hook->priv_data = priv_data;
158 if (add_io_hook(io_map, io_hook) != 0) {
166 int v3_unhook_io_port(vmm_io_map_t * io_map, uint_t port) {
167 vmm_io_hook_t * hook = v3_get_io_hook(io_map, port);
173 remove_io_hook(io_map, hook);
178 vmm_io_hook_t * v3_get_io_hook(vmm_io_map_t * io_map, uint_t port) {
179 vmm_io_hook_t * tmp_hook;
180 FOREACH_IO_HOOK(*io_map, tmp_hook) {
181 if (tmp_hook->port == port) {
190 void PrintDebugIOMap(vmm_io_map_t * io_map) {
191 vmm_io_hook_t * iter = io_map->head;
193 PrintDebug("VMM IO Map (Entries=%d)\n", io_map->num_ports);
196 PrintDebug("IO Port: %hu (Read=%x) (Write=%x)\n", iter->port, iter->read, iter->write);