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.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
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.
14 * Author: Jack Lange <jarusl@cs.northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
22 #include <palacios/vmm.h>
23 #include <palacios/vmm_dev_mgr.h>
24 #include <palacios/vmm_io.h>
28 #define BOCHS_PORT1 0x400
29 #define BOCHS_PORT2 0x401
30 #define BOCHS_INFO_PORT 0x402
31 #define BOCHS_DEBUG_PORT 0x403
33 #define BOCHS_CONSOLE_PORT 0xe9
37 char debug_buf[BUF_SIZE];
40 char info_buf[BUF_SIZE];
43 char cons_buf[BUF_SIZE];
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;
51 state->info_buf[state->info_offset++] = *(char*)src;
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;
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;
67 state->debug_buf[state->debug_offset++] = *(char*)src;
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;
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;
83 state->cons_buf[state->cons_offset++] = *(char *)src;
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;
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;
100 PrintDebug(">0x%.2x\n", *(uchar_t*)src);
103 PrintDebug(">0x%.4x\n", *(ushort_t*)src);
106 PrintDebug(">0x%.8x\n", *(uint_t*)src);
109 PrintError("Invalid length in handle_gen_write\n");
120 static int debug_free(struct vm_device * dev) {
121 struct debug_state * state = dev->private_data;
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);
136 static struct v3_device_ops dev_ops = {
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");
151 state = (struct debug_state *)V3_Malloc(sizeof(struct debug_state));
153 V3_ASSERT(state != NULL);
155 PrintDebug("Creating Bochs Debug Device\n");
156 struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state);
158 if (v3_attach_device(vm, dev) == -1) {
159 PrintError("Could not attach device %s\n", dev_id);
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);
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);
179 PrintError("Could not hook Bochs Debug IO Ports\n");
180 v3_detach_device(dev);
188 device_register("BOCHS_DEBUG", debug_init);