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;
47 io_hook->prev = tmp_hook;
48 io_hook->next = tmp_hook->next;
51 tmp_hook->next->prev = io_hook;
54 tmp_hook->next = io_hook;
63 int remove_io_hook(vmm_io_map_t * io_map, vmm_io_hook_t * io_hook) {
64 if (io_map->head == io_hook) {
65 io_map->head = io_hook->next;
66 } else if (io_hook->prev) {
67 io_hook->prev->next = io_hook->next;
70 // data corruption failure
74 io_hook->next->prev = io_hook->prev;
85 static int default_write(ushort_t port, void *src, uint_t length, void * priv_data) {
89 __asm__ __volatile__ (
92 : "a" (*dst), "Nd" (port)
94 } else if (length == 2) {
95 __asm__ __volatile__ (
98 : "a" (*dst), "Nd" (port)
100 } else if (length == 4) {
101 __asm__ __volatile__ (
104 : "a" (*dst), "Nd" (port)
111 static int default_read(ushort_t port, void * dst, uint_t length, void * priv_data)
117 __asm__ __volatile__ (
129 int hook_io_port(vmm_io_map_t * io_map, uint_t port,
130 int (*read)(ushort_t port, void * dst, uint_t length, void * priv_data),
131 int (*write)(ushort_t port, void * src, uint_t length, void * priv_data),
133 vmm_io_hook_t * io_hook = os_hooks->malloc(sizeof(vmm_io_hook_t));
135 io_hook->port = port;
138 io_hook->read = &default_read;
140 io_hook->read = read;
144 io_hook->write = &default_write;
146 io_hook->write = write;
149 io_hook->next = NULL;
150 io_hook->prev = NULL;
152 io_hook->priv_data = priv_data;
154 if (add_io_hook(io_map, io_hook) != 0) {
162 int unhook_io_port(vmm_io_map_t * io_map, uint_t port) {
163 vmm_io_hook_t * hook = get_io_hook(io_map, port);
169 remove_io_hook(io_map, hook);
174 vmm_io_hook_t * get_io_hook(vmm_io_map_t * io_map, uint_t port) {
175 vmm_io_hook_t * tmp_hook;
176 FOREACH_IO_HOOK(*io_map, tmp_hook) {
177 if (tmp_hook->port == port) {
186 void PrintDebugIOMap(vmm_io_map_t * io_map) {
187 vmm_io_hook_t * iter = io_map->head;
189 PrintDebug("VMM IO Map (Entries=%d)\n", io_map->num_ports);
192 PrintDebug("IO Port: %hu (Read=%x) (Write=%x)\n", iter->port, iter->read, iter->write);