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.


integrated new configuration system
[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
25 #define BUF_SIZE 1024
26
27 #define BOCHS_PORT1 0x400
28 #define BOCHS_PORT2 0x401
29 #define BOCHS_INFO_PORT 0x402
30 #define BOCHS_DEBUG_PORT 0x403
31
32 #define BOCHS_CONSOLE_PORT 0xe9
33
34
35 struct debug_state {
36     char debug_buf[BUF_SIZE];
37     uint_t debug_offset;
38
39     char info_buf[BUF_SIZE];
40     uint_t info_offset;
41
42     char cons_buf[BUF_SIZE];
43     uint_t cons_offset;
44 };
45
46 static int handle_info_write(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
47     struct debug_state * state = (struct debug_state *)dev->private_data;
48
49     state->info_buf[state->info_offset++] = *(char*)src;
50
51     if ((*(char*)src == 0xa) ||  (state->info_offset == (BUF_SIZE - 1))) {
52         PrintDebug("BOCHSINFO>%s", state->info_buf);
53         memset(state->info_buf, 0, BUF_SIZE);
54         state->info_offset = 0;
55     }
56
57     return length;
58 }
59
60
61 static int handle_debug_write(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
62     struct debug_state * state = (struct debug_state *)dev->private_data;
63
64     state->debug_buf[state->debug_offset++] = *(char*)src;
65
66     if ((*(char*)src == 0xa) ||  (state->debug_offset == (BUF_SIZE - 1))) {
67         PrintDebug("BOCHSDEBUG>%s", state->debug_buf);
68         memset(state->debug_buf, 0, BUF_SIZE);
69         state->debug_offset = 0;
70     }
71
72     return length;
73 }
74
75
76 static int handle_console_write(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
77     struct debug_state * state = (struct debug_state *)dev->private_data;
78
79     state->cons_buf[state->cons_offset++] = *(char*)src;
80
81     if ((*(char*)src == 0xa) ||  (state->cons_offset == (BUF_SIZE - 1))) {
82         PrintDebug("BOCHSCONSOLE>%s", state->cons_buf);
83         memset(state->cons_buf, 0, BUF_SIZE);
84         state->cons_offset = 0;
85     }
86
87     return length;
88 }
89
90
91 static int handle_gen_write(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
92
93     switch (length) {
94         case 1:
95             PrintDebug(">0x%.2x\n", *(uchar_t*)src);
96             break;
97         case 2:
98             PrintDebug(">0x%.4x\n", *(ushort_t*)src);
99             break;
100         case 4:
101             PrintDebug(">0x%.8x\n", *(uint_t*)src);
102             break;
103         default:
104             PrintError("Invalid length in handle_gen_write\n");
105             return -1;
106             break;
107     }
108
109     return length;
110 }
111
112
113
114
115 static int debug_free(struct vm_device * dev) {
116     v3_dev_unhook_io(dev, BOCHS_PORT1);
117     v3_dev_unhook_io(dev, BOCHS_PORT2);
118     v3_dev_unhook_io(dev, BOCHS_INFO_PORT);
119     v3_dev_unhook_io(dev, BOCHS_DEBUG_PORT);
120
121     return 0;
122 };
123
124
125
126
127 static struct v3_device_ops dev_ops = {
128     .free = debug_free,
129     .reset = NULL,
130     .start = NULL,
131     .stop = NULL,
132 };
133
134
135
136
137 static int debug_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
138     struct debug_state * state = NULL;
139     char * name = v3_cfg_val(cfg, "name");
140
141     state = (struct debug_state *)V3_Malloc(sizeof(struct debug_state));
142
143     V3_ASSERT(state != NULL);
144
145     PrintDebug("Creating Bochs Debug Device\n");
146     struct vm_device * dev = v3_allocate_device(name, &dev_ops, state);
147
148     if (v3_attach_device(vm, dev) == -1) {
149         PrintError("Could not attach device %s\n", name);
150         return -1;
151     }
152
153     state->debug_offset = 0;
154     state->info_offset = 0;
155     memset(state->debug_buf, 0, BUF_SIZE);
156     memset(state->info_buf, 0, BUF_SIZE);
157
158
159     v3_dev_hook_io(dev, BOCHS_PORT1,  NULL, &handle_gen_write);
160     v3_dev_hook_io(dev, BOCHS_PORT2, NULL, &handle_gen_write);
161     v3_dev_hook_io(dev, BOCHS_INFO_PORT, NULL, &handle_info_write);
162     v3_dev_hook_io(dev, BOCHS_DEBUG_PORT, NULL, &handle_debug_write);
163     v3_dev_hook_io(dev, BOCHS_CONSOLE_PORT, NULL, &handle_console_write);
164     
165   
166     return 0;
167 }
168
169
170 device_register("BOCHS_DEBUG", debug_init);