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.


12f22c9d8ca8afe906c91da6c480d65b0f84e263
[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, void * cfg_data) {
138    struct debug_state * state = NULL;
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("BOCHS_DEBUG", &dev_ops, state);
146
147     if (v3_attach_device(vm, dev) == -1) {
148         PrintError("Could not attach device %s\n", "BOCHS_DEBUG");
149         return -1;
150     }
151
152     state->debug_offset = 0;
153     state->info_offset = 0;
154     memset(state->debug_buf, 0, BUF_SIZE);
155     memset(state->info_buf, 0, BUF_SIZE);
156
157
158     v3_dev_hook_io(dev, BOCHS_PORT1,  NULL, &handle_gen_write);
159     v3_dev_hook_io(dev, BOCHS_PORT2, NULL, &handle_gen_write);
160     v3_dev_hook_io(dev, BOCHS_INFO_PORT, NULL, &handle_info_write);
161     v3_dev_hook_io(dev, BOCHS_DEBUG_PORT, NULL, &handle_debug_write);
162     v3_dev_hook_io(dev, BOCHS_CONSOLE_PORT, NULL, &handle_console_write);
163     
164   
165     return 0;
166 }
167
168
169 device_register("BOCHS_DEBUG", debug_init);