Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


reworked device IO hook framework
[palacios.git] / palacios / src / devices / bochs_debug.c
1 /* 
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
11  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Jack Lange <jarusl@cs.northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20
21
22 #include <palacios/vmm.h>
23 #include <palacios/vmm_dev_mgr.h>
24 #include <palacios/vmm_io.h>
25
26 #define BUF_SIZE 1024
27
28 #define BOCHS_PORT1 0x400
29 #define BOCHS_PORT2 0x401
30 #define BOCHS_INFO_PORT 0x402
31 #define BOCHS_DEBUG_PORT 0x403
32
33 #define BOCHS_CONSOLE_PORT 0xe9
34
35
36 struct debug_state {
37     char debug_buf[BUF_SIZE];
38     uint_t debug_offset;
39
40     char info_buf[BUF_SIZE];
41     uint_t info_offset;
42
43     char cons_buf[BUF_SIZE];
44     uint_t cons_offset;
45 };
46
47 static int handle_info_write(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
48     struct debug_state * state = (struct debug_state *)priv_data;
49
50     state->info_buf[state->info_offset++] = *(char*)src;
51
52     if ((*(char*)src == 0xa) ||  (state->info_offset == (BUF_SIZE - 1))) {
53         PrintDebug("BOCHSINFO>%s", state->info_buf);
54         memset(state->info_buf, 0, BUF_SIZE);
55         state->info_offset = 0;
56     }
57
58     return length;
59 }
60
61
62 static int handle_debug_write(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
63     struct debug_state * state = (struct debug_state *)priv_data;
64
65     state->debug_buf[state->debug_offset++] = *(char*)src;
66
67     if ((*(char*)src == 0xa) ||  (state->debug_offset == (BUF_SIZE - 1))) {
68         PrintDebug("BOCHSDEBUG>%s", state->debug_buf);
69         memset(state->debug_buf, 0, BUF_SIZE);
70         state->debug_offset = 0;
71     }
72
73     return length;
74 }
75
76
77 static int handle_console_write(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
78     struct debug_state * state = (struct debug_state *)priv_data;
79
80     state->cons_buf[state->cons_offset++] = *(char *)src;
81
82     if ((*(char *)src == 0xa) ||  (state->cons_offset == (BUF_SIZE - 1))) {
83         V3_Print("BOCHSCONSOLE>%s", state->cons_buf);
84         memset(state->cons_buf, 0, BUF_SIZE);
85         state->cons_offset = 0;
86     }
87
88     return length;
89 }
90
91
92 static int handle_gen_write(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data)  {
93     
94     switch (length) {
95         case 1:
96             PrintDebug(">0x%.2x\n", *(uchar_t*)src);
97             break;
98         case 2:
99             PrintDebug(">0x%.4x\n", *(ushort_t*)src);
100             break;
101         case 4:
102             PrintDebug(">0x%.8x\n", *(uint_t*)src);
103             break;
104         default:
105             PrintError("Invalid length in handle_gen_write\n");
106             return -1;
107             break;
108     }
109
110     return length;
111 }
112
113
114
115
116 static int debug_free(struct vm_device * dev) {
117     struct debug_state * state = dev->private_data;
118
119     V3_Free(state);
120
121     return 0;
122 };
123
124
125
126
127 static struct v3_device_ops dev_ops = {
128     .free = debug_free,
129
130 };
131
132
133
134
135 static int debug_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
136     struct debug_state * state = NULL;
137     char * dev_id = v3_cfg_val(cfg, "ID");
138     int ret = 0;
139
140     state = (struct debug_state *)V3_Malloc(sizeof(struct debug_state));
141
142     V3_ASSERT(state != NULL);
143
144     PrintDebug("Creating Bochs Debug Device\n");
145     struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state);
146
147     if (v3_attach_device(vm, dev) == -1) {
148         PrintError("Could not attach device %s\n", dev_id);
149         V3_Free(state);
150         return -1;
151     }
152
153     state->debug_offset = 0;
154     state->info_offset = 0;
155     state->cons_offset = 0;
156     memset(state->debug_buf, 0, BUF_SIZE);
157     memset(state->info_buf, 0, BUF_SIZE);
158     memset(state->cons_buf, 0, BUF_SIZE);
159
160
161     ret |= v3_dev_hook_io(dev, BOCHS_PORT1,  NULL, &handle_gen_write);
162     ret |= v3_dev_hook_io(dev, BOCHS_PORT2, NULL, &handle_gen_write);
163     ret |= v3_dev_hook_io(dev, BOCHS_INFO_PORT, NULL, &handle_info_write);
164     ret |= v3_dev_hook_io(dev, BOCHS_DEBUG_PORT, NULL, &handle_debug_write);
165     ret |= v3_dev_hook_io(dev, BOCHS_CONSOLE_PORT, NULL, &handle_console_write);
166     
167     if (ret != 0) {
168         PrintError("Could not hook Bochs Debug IO Ports\n");
169         v3_detach_device(dev);
170         return -1;
171     }
172   
173     return 0;
174 }
175
176
177 device_register("BOCHS_DEBUG", debug_init);