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".
21 #include <devices/bochs_debug.h>
22 #include <palacios/vmm.h>
26 #define BOCHS_PORT1 0x400
27 #define BOCHS_PORT2 0x401
28 #define BOCHS_INFO_PORT 0x402
29 #define BOCHS_DEBUG_PORT 0x403
31 #define BOCHS_CONSOLE_PORT 0xe9
35 char debug_buf[BUF_SIZE];
38 char info_buf[BUF_SIZE];
41 char cons_buf[BUF_SIZE];
45 static int handle_info_write(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
46 struct debug_state * state = (struct debug_state *)dev->private_data;
48 state->info_buf[state->info_offset++] = *(char*)src;
50 if ((*(char*)src == 0xa) || (state->info_offset == (BUF_SIZE - 1))) {
51 PrintDebug("BOCHSINFO>%s", state->info_buf);
52 memset(state->info_buf, 0, BUF_SIZE);
53 state->info_offset = 0;
60 static int handle_debug_write(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
61 struct debug_state * state = (struct debug_state *)dev->private_data;
63 state->debug_buf[state->debug_offset++] = *(char*)src;
65 if ((*(char*)src == 0xa) || (state->debug_offset == (BUF_SIZE - 1))) {
66 PrintDebug("BOCHSDEBUG>%s", state->debug_buf);
67 memset(state->debug_buf, 0, BUF_SIZE);
68 state->debug_offset = 0;
75 static int handle_console_write(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
76 struct debug_state * state = (struct debug_state *)dev->private_data;
78 state->cons_buf[state->cons_offset++] = *(char*)src;
80 if ((*(char*)src == 0xa) || (state->cons_offset == (BUF_SIZE - 1))) {
81 PrintDebug("BOCHSCONSOLE>%s", state->cons_buf);
82 memset(state->cons_buf, 0, BUF_SIZE);
83 state->cons_offset = 0;
90 static int handle_gen_write(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
94 PrintDebug(">0x%.2x\n", *(uchar_t*)src);
97 PrintDebug(">0x%.4x\n", *(ushort_t*)src);
100 PrintDebug(">0x%.8x\n", *(uint_t*)src);
103 PrintError("Invalid length in handle_gen_write\n");
112 static int debug_init(struct vm_device * dev) {
113 struct debug_state * state = (struct debug_state *)dev->private_data;
115 state->debug_offset = 0;
116 state->info_offset = 0;
117 memset(state->debug_buf, 0, BUF_SIZE);
118 memset(state->info_buf, 0, BUF_SIZE);
121 v3_dev_hook_io(dev, BOCHS_PORT1, NULL, &handle_gen_write);
122 v3_dev_hook_io(dev, BOCHS_PORT2, NULL, &handle_gen_write);
123 v3_dev_hook_io(dev, BOCHS_INFO_PORT, NULL, &handle_info_write);
124 v3_dev_hook_io(dev, BOCHS_DEBUG_PORT, NULL, &handle_debug_write);
125 v3_dev_hook_io(dev, BOCHS_CONSOLE_PORT, NULL, &handle_console_write);
131 static int debug_deinit(struct vm_device * dev) {
132 v3_dev_unhook_io(dev, BOCHS_PORT1);
133 v3_dev_unhook_io(dev, BOCHS_PORT2);
134 v3_dev_unhook_io(dev, BOCHS_INFO_PORT);
135 v3_dev_unhook_io(dev, BOCHS_DEBUG_PORT);
143 static struct vm_device_ops dev_ops = {
145 .deinit = debug_deinit,
152 struct vm_device * v3_create_bochs_debug() {
153 struct debug_state * state = NULL;
155 state = (struct debug_state *)V3_Malloc(sizeof(struct debug_state));
157 V3_ASSERT(state != NULL);
159 PrintDebug("Creating Bochs Debug Device\n");
160 struct vm_device * device = v3_create_device("BOCHS Debug", &dev_ops, state);