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.


Context-based output infrastructure (V3_Print, etc) and modifications to use it
[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 #include <palacios/vm_guest.h>
26
27 #define BUF_SIZE 1024
28
29 #define BOCHS_PORT1 0x400
30 #define BOCHS_PORT2 0x401
31 #define BOCHS_INFO_PORT 0x402
32 #define BOCHS_DEBUG_PORT 0x403
33
34 #define BOCHS_CONSOLE_PORT 0xe9
35
36
37 struct debug_state {
38     char debug_buf[BUF_SIZE];
39     uint_t debug_offset;
40
41     char info_buf[BUF_SIZE];
42     uint_t info_offset;
43
44     char cons_buf[BUF_SIZE];
45     uint_t cons_offset;
46 };
47
48 static int handle_info_write(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
49     struct debug_state * state = (struct debug_state *)priv_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(core->vm_info, core, "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 debug_state * state = (struct debug_state *)priv_data;
65
66     state->debug_buf[state->debug_offset++] = *(char*)src;
67
68     if ((*(char*)src == 0xa) ||  (state->debug_offset == (BUF_SIZE - 1))) {
69         PrintDebug(core->vm_info, core, "BOCHSDEBUG>%s", state->debug_buf);
70         memset(state->debug_buf, 0, BUF_SIZE);
71         state->debug_offset = 0;
72     }
73
74     return length;
75 }
76
77
78 static int handle_console_write(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
79     struct debug_state * state = (struct debug_state *)priv_data;
80
81     state->cons_buf[state->cons_offset++] = *(char *)src;
82
83     if ((*(char *)src == 0xa) ||  (state->cons_offset == (BUF_SIZE - 1))) {
84         V3_Print(core->vm_info, core, "BOCHSCONSOLE>%s", state->cons_buf);
85         memset(state->cons_buf, 0, BUF_SIZE);
86         state->cons_offset = 0;
87     }
88
89     return length;
90 }
91
92
93 static int handle_gen_write(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data)  {
94     
95     switch (length) {
96         case 1:
97             PrintDebug(core->vm_info, core, ">0x%.2x\n", *(uchar_t*)src);
98             break;
99         case 2:
100             PrintDebug(core->vm_info, core, ">0x%.4x\n", *(ushort_t*)src);
101             break;
102         case 4:
103             PrintDebug(core->vm_info, core, ">0x%.8x\n", *(uint_t*)src);
104             break;
105         default:
106             PrintError(core->vm_info, core, "Invalid length in handle_gen_write\n");
107             return -1;
108             break;
109     }
110
111     return length;
112 }
113
114
115
116
117 static int debug_free(struct debug_state * state) {
118
119     V3_Free(state);
120     return 0;
121 };
122
123
124
125
126 static struct v3_device_ops dev_ops = {
127     .free = (int (*)(void *))debug_free,
128
129 };
130
131
132
133
134 static int debug_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
135     struct debug_state * state = NULL;
136     char * dev_id = v3_cfg_val(cfg, "ID");
137     int ret = 0;
138
139     state = (struct debug_state *)V3_Malloc(sizeof(struct debug_state));
140
141     if (state == NULL) {
142         PrintError(vm, VCORE_NONE, "Could not allocate bochs debug state\n");
143         return -1;
144     }
145
146     PrintDebug(vm, VCORE_NONE, "Creating Bochs Debug Device\n");
147     struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, state);
148
149     if (dev == NULL) {
150         PrintError(vm, VCORE_NONE, "Could not attach device %s\n", dev_id);
151         V3_Free(state);
152         return -1;
153     }
154
155     state->debug_offset = 0;
156     state->info_offset = 0;
157     state->cons_offset = 0;
158     memset(state->debug_buf, 0, BUF_SIZE);
159     memset(state->info_buf, 0, BUF_SIZE);
160     memset(state->cons_buf, 0, BUF_SIZE);
161
162
163     ret |= v3_dev_hook_io(dev, BOCHS_PORT1,  NULL, &handle_gen_write);
164     ret |= v3_dev_hook_io(dev, BOCHS_PORT2, NULL, &handle_gen_write);
165     ret |= v3_dev_hook_io(dev, BOCHS_INFO_PORT, NULL, &handle_info_write);
166     ret |= v3_dev_hook_io(dev, BOCHS_DEBUG_PORT, NULL, &handle_debug_write);
167     ret |= v3_dev_hook_io(dev, BOCHS_CONSOLE_PORT, NULL, &handle_console_write);
168     
169     if (ret != 0) {
170         PrintError(vm, VCORE_NONE, "Could not hook Bochs Debug IO Ports\n");
171         v3_remove_device(dev);
172         return -1;
173     }
174   
175     return 0;
176 }
177
178
179 device_register("BOCHS_DEBUG", debug_init);