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.


adba8356fb8b4d03f01b518cacdf841efef0cf66
[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 vm_device * dev = priv_data;
49     struct debug_state * state = (struct debug_state *)dev->private_data;
50
51     state->info_buf[state->info_offset++] = *(char*)src;
52
53     if ((*(char*)src == 0xa) ||  (state->info_offset == (BUF_SIZE - 1))) {
54         PrintDebug("BOCHSINFO>%s", state->info_buf);
55         memset(state->info_buf, 0, BUF_SIZE);
56         state->info_offset = 0;
57     }
58
59     return length;
60 }
61
62
63 static int handle_debug_write(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
64     struct vm_device * dev = priv_data;
65     struct debug_state * state = (struct debug_state *)dev->private_data;
66
67     state->debug_buf[state->debug_offset++] = *(char*)src;
68
69     if ((*(char*)src == 0xa) ||  (state->debug_offset == (BUF_SIZE - 1))) {
70         PrintDebug("BOCHSDEBUG>%s", state->debug_buf);
71         memset(state->debug_buf, 0, BUF_SIZE);
72         state->debug_offset = 0;
73     }
74
75     return length;
76 }
77
78
79 static int handle_console_write(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
80     struct vm_device * dev = priv_data;
81     struct debug_state * state = (struct debug_state *)dev->private_data;
82
83     state->cons_buf[state->cons_offset++] = *(char *)src;
84
85     if ((*(char *)src == 0xa) ||  (state->cons_offset == (BUF_SIZE - 1))) {
86         V3_Print("BOCHSCONSOLE>%s", state->cons_buf);
87         memset(state->cons_buf, 0, BUF_SIZE);
88         state->cons_offset = 0;
89     }
90
91     return length;
92 }
93
94
95 static int handle_gen_write(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data)  {
96     //struct vm_device * dev = priv_data;
97     
98     switch (length) {
99         case 1:
100             PrintDebug(">0x%.2x\n", *(uchar_t*)src);
101             break;
102         case 2:
103             PrintDebug(">0x%.4x\n", *(ushort_t*)src);
104             break;
105         case 4:
106             PrintDebug(">0x%.8x\n", *(uint_t*)src);
107             break;
108         default:
109             PrintError("Invalid length in handle_gen_write\n");
110             return -1;
111             break;
112     }
113
114     return length;
115 }
116
117
118
119
120 static int debug_free(struct vm_device * dev) {
121     struct debug_state * state = dev->private_data;
122
123     v3_unhook_io_port(dev->vm, BOCHS_PORT1);
124     v3_unhook_io_port(dev->vm, BOCHS_PORT2);
125     v3_unhook_io_port(dev->vm, BOCHS_INFO_PORT);
126     v3_unhook_io_port(dev->vm, BOCHS_DEBUG_PORT);
127
128     V3_Free(state);
129
130     return 0;
131 };
132
133
134
135
136 static struct v3_device_ops dev_ops = {
137     .free = debug_free,
138     .reset = NULL,
139     .start = NULL,
140     .stop = NULL,
141 };
142
143
144
145
146 static int debug_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
147     struct debug_state * state = NULL;
148     char * dev_id = v3_cfg_val(cfg, "ID");
149     int ret = 0;
150
151     state = (struct debug_state *)V3_Malloc(sizeof(struct debug_state));
152
153     V3_ASSERT(state != NULL);
154
155     PrintDebug("Creating Bochs Debug Device\n");
156     struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state);
157
158     if (v3_attach_device(vm, dev) == -1) {
159         PrintError("Could not attach device %s\n", dev_id);
160         V3_Free(state);
161         return -1;
162     }
163
164     state->debug_offset = 0;
165     state->info_offset = 0;
166     state->cons_offset = 0;
167     memset(state->debug_buf, 0, BUF_SIZE);
168     memset(state->info_buf, 0, BUF_SIZE);
169     memset(state->cons_buf, 0, BUF_SIZE);
170
171
172     ret |= v3_hook_io_port(vm, BOCHS_PORT1,  NULL, &handle_gen_write, dev);
173     ret |= v3_hook_io_port(vm, BOCHS_PORT2, NULL, &handle_gen_write, dev);
174     ret |= v3_hook_io_port(vm, BOCHS_INFO_PORT, NULL, &handle_info_write, dev);
175     ret |= v3_hook_io_port(vm, BOCHS_DEBUG_PORT, NULL, &handle_debug_write, dev);
176     ret |= v3_hook_io_port(vm, BOCHS_CONSOLE_PORT, NULL, &handle_console_write, dev);
177     
178     if (ret != 0) {
179         PrintError("Could not hook Bochs Debug IO Ports\n");
180         v3_detach_device(dev);
181         return -1;
182     }
183   
184     return 0;
185 }
186
187
188 device_register("BOCHS_DEBUG", debug_init);