extern ulong_t s_ramdiskSize;
-#define SPEAKER_PORT 0x61
-
-static inline void VM_Out_Byte(ushort_t port, uchar_t value)
-{
- __asm__ __volatile__ (
- "outb %b0, %w1"
- :
- : "a" (value), "Nd" (port)
- );
-}
-
-/*
- * Read a byte from an I/O port.
- */
-static inline uchar_t VM_In_Byte(ushort_t port)
-{
- uchar_t value;
-
- __asm__ __volatile__ (
- "inb %w1, %b0"
- : "=a" (value)
- : "Nd" (port)
- );
-
- return value;
-}
-
-
-
-
-int IO_Read(ushort_t port, void * dst, uint_t length, void * priv_data) {
-
- if (length != 1) {
- return 0;
- }
-
- *(uchar_t*)dst = VM_In_Byte(port);
- return 1;
-}
-
-
-
-int IO_Write(ushort_t port, void * src, uint_t length, void * priv_data) {
-
- if (length != 1) {
- return 0;
- }
-
- VM_Out_Byte(port, *(uchar_t *)src);
-
- return 1;
-}
-
-
-int IO_Read_to_Serial(ushort_t port, void * dst, uint_t length, void * priv_data) {
- PrintBoth("Input from Guest on port %d (0x%x) Length=%d\n", port, port, length);
-
- return 0;
-}
-
-
-char * bochs_debug_buf = NULL;
-int bochs_debug_offset = 0;
-
-char * bochs_info_buf = NULL;
-int bochs_info_offset = 0;
-
-
-int IO_BOCHS_debug(ushort_t port, void * src, uint_t length, void * priv_data) {
- if (!bochs_debug_buf) {
- bochs_debug_buf = (char*)Malloc(1024);
- }
-
- bochs_debug_buf[bochs_debug_offset++] = *(char*)src;
-
- if ((*(char*)src == 0xa) || (bochs_debug_offset == 1023)) {
- SerialPrint("BOCHSDEBUG>%s", bochs_debug_buf);
- memset(bochs_debug_buf, 0, 1024);
- bochs_debug_offset = 0;
- }
-
- return length;
-}
-
-int IO_BOCHS_info(ushort_t port, void * src, uint_t length, void * priv_data) {
- if (!bochs_info_buf) {
- bochs_info_buf = (char*)Malloc(1024);
- }
-
- bochs_info_buf[bochs_info_offset++] = *(char*)src;
-
- if ((*(char*)src == 0xa) || (bochs_info_offset == 1023)) {
- SerialPrint("BOCHSINFO>%s", bochs_info_buf);
- memset(bochs_info_buf, 0, 1024);
- bochs_info_offset = 0;
- }
-
- return length;
-}
-
-
-int IO_Write_to_Serial(ushort_t port, void * src, uint_t length, void * priv_data) {
- SerialPrint("Output from Guest on port %d (0x%x) Length=%d\n", port, port, length);
- switch (length) {
-
- case 1:
- SerialPrint(">0x%.2x\n", *(char*)src);
- break;
- case 2:
- SerialPrint(">0x%.4x\n", *(ushort_t*)src);
- break;
- case 4:
- SerialPrint(">0x%.8x\n", *(uint_t*)src);
- break;
- default:
- break;
- }
-
- // SerialMemDump(src, length);
- return length;
-}
-
-
-
-void BuzzVM()
-{
- int x;
- int j;
- unsigned char init;
-
-#if 0
- __asm__ __volatile__ (
- "popf"
- );
-
-#endif
-
- PrintBoth("Starting To Buzz\n");
-
- init=VM_In_Byte(SPEAKER_PORT);
-
- while (1) {
- VM_Out_Byte(SPEAKER_PORT, init|0x2);
- for (j=0;j<1000000;j++) {
- x+=j;
- }
- VM_Out_Byte(SPEAKER_PORT, init);
- for (j=0;j<1000000;j++) {
- x+=j;
- }
- }
-}
-
-
-/*
-int passthrough_mem_read(void * guest_addr, void * dst, uint_t length, void * priv_data) {
- memcpy(dst, (void*)guest_addr, length);
- return length;
-}
-
-int passthrough_mem_write(void * guest_addr, void * src, uint_t length, void * priv_data) {
- memcpy((void*)guest_addr, src, length);
- return length;
-}
-*/
-
-
-/* We need a configuration mechanism, so we can wrap this completely inside the VMM code,
- * with no pollution into the HOST OS
- */
-
int RunVMM(struct Boot_Info * bootInfo) {
struct vmm_os_hooks os_hooks;
struct vmm_ctrl_ops vmm_ops;
-
vm_info = (vmm_ops).allocate_guest();
Init_Stubs(vm_info);
PrintBoth("Configured guest\n");
-
- //v3_hook_io_port(&vm_info, 0x05, &IO_Read, &IO_Write_to_Serial, NULL);
-
- //v3_hook_io_port(vm_info, 0x61, &IO_Read, &IO_Write, NULL);
- //v3_hook_io_port(vm_info, 0x400, &IO_Read, &IO_Write_to_Serial, NULL);
- //v3_hook_io_port(vm_info, 0x401, &IO_Read, &IO_Write_to_Serial, NULL);
- //v3_hook_io_port(vm_info, 0x402, &IO_Read, &IO_BOCHS_info, NULL);
- //v3_hook_io_port(vm_info, 0x403, &IO_Read, &IO_BOCHS_debug, NULL);
-
-
(vmm_ops).init_guest(vm_info);
PrintBoth("Starting Guest\n");
//Clear_Screen();
-DEVICE_C_SRCS := generic.c keyboard.c nvram.c timer.c simple_pic.c 8259a.c 8254.c serial.c ramdisk.c cdrom.c
+DEVICE_C_SRCS := generic.c keyboard.c nvram.c timer.c simple_pic.c 8259a.c 8254.c serial.c ramdisk.c cdrom.c bochs_debug.c
DEVICE_C_OBJS := $(DEVICE_C_SRCS:%.c=devices/%.o)
--- /dev/null
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#ifndef __DEVICES_BOCHS_DEBUG_H__
+#define __DEVICES_BOCHS_DEBUG_H__
+
+#ifdef __V3VEE__
+
+#include <palacios/vm_dev.h>
+
+struct vm_device * create_bochs_debug();
+
+
+#endif // ! __V3VEE__
+
+#endif
--- /dev/null
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+
+#include <devices/bochs_debug.h>
+#include <palacios/vmm.h>
+
+#define BUF_SIZE 1024
+
+#define BOCHS_PORT1 0x400
+#define BOCHS_PORT2 0x401
+#define BOCHS_INFO_PORT 0x402
+#define BOCHS_DEBUG_PORT 0x403
+
+
+
+struct debug_state {
+ char debug_buf[BUF_SIZE];
+ uint_t debug_offset;
+
+ char info_buf[BUF_SIZE];
+ uint_t info_offset;
+};
+
+static int handle_info_write(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+ struct debug_state * state = (struct debug_state *)dev->private_data;
+
+ state->info_buf[state->info_offset++] = *(char*)src;
+
+ if ((*(char*)src == 0xa) || (state->info_offset == (BUF_SIZE - 1))) {
+ PrintDebug("BOCHSINFO>%s", state->info_buf);
+ memset(state->info_buf, 0, BUF_SIZE);
+ state->info_offset = 0;
+ }
+
+ return length;
+}
+
+
+static int handle_debug_write(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+ struct debug_state * state = (struct debug_state *)dev->private_data;
+
+ state->debug_buf[state->debug_offset++] = *(char*)src;
+
+ if ((*(char*)src == 0xa) || (state->debug_offset == (BUF_SIZE - 1))) {
+ PrintDebug("BOCHSDEBUG>%s", state->debug_buf);
+ memset(state->debug_buf, 0, BUF_SIZE);
+ state->debug_offset = 0;
+ }
+
+ return length;
+}
+
+
+static int handle_gen_write(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+
+ switch (length) {
+ case 1:
+ PrintDebug(">0x%.2x\n", *(uchar_t*)src);
+ break;
+ case 2:
+ PrintDebug(">0x%.4x\n", *(ushort_t*)src);
+ break;
+ case 4:
+ PrintDebug(">0x%.8x\n", *(uint_t*)src);
+ break;
+ default:
+ PrintError("Invalid length in handle_gen_write\n");
+ return -1;
+ break;
+ }
+
+ return length;
+}
+
+
+static int debug_init(struct vm_device * dev) {
+ struct debug_state * state = (struct debug_state *)dev->private_data;
+
+ state->debug_offset = 0;
+ state->info_offset = 0;
+ memset(state->debug_buf, 0, BUF_SIZE);
+ memset(state->info_buf, 0, BUF_SIZE);
+
+
+ dev_hook_io(dev, BOCHS_PORT1, NULL, &handle_gen_write);
+ dev_hook_io(dev, BOCHS_PORT2, NULL, &handle_gen_write);
+ dev_hook_io(dev, BOCHS_INFO_PORT, NULL, &handle_info_write);
+ dev_hook_io(dev, BOCHS_DEBUG_PORT, NULL, &handle_debug_write);
+
+ return 0;
+}
+
+static int debug_deinit(struct vm_device * dev) {
+ dev_unhook_io(dev, BOCHS_PORT1);
+ dev_unhook_io(dev, BOCHS_PORT2);
+ dev_unhook_io(dev, BOCHS_INFO_PORT);
+ dev_unhook_io(dev, BOCHS_DEBUG_PORT);
+
+ return 0;
+};
+
+
+
+
+static struct vm_device_ops dev_ops = {
+ .init = debug_init,
+ .deinit = debug_deinit,
+ .reset = NULL,
+ .start = NULL,
+ .stop = NULL,
+};
+
+
+struct vm_device * create_bochs_debug() {
+ struct debug_state * state = NULL;
+
+ state = (struct debug_state *)V3_Malloc(sizeof(struct debug_state));
+
+ V3_ASSERT(state != NULL);
+
+ PrintDebug("Creating Bochs Debug Device\n");
+ struct vm_device * device = create_device("BOCHS Debug", &dev_ops, state);
+
+
+
+ return device;
+}
char buffer[SERIAL_BUF_LEN];
};
-int queue_data(struct serial_buffer * buf, char data) {
+static int queue_data(struct serial_buffer * buf, char data) {
uint_t next_loc = (buf->head + 1) % SERIAL_BUF_LEN;
if (next_loc == buf->tail) {
return 0;
}
-int dequeue_data(struct serial_buffer * buf, char * data) {
+static int dequeue_data(struct serial_buffer * buf, char * data) {
uint_t next_tail = (buf->tail + 1) % SERIAL_BUF_LEN;
if (buf->head == buf->tail) {
};
-int write_data_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int write_data_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
struct serial_state * state = (struct serial_state *)dev->private_data;
char * val = (char *)src;
PrintDebug("Write to Data Port 0x%x (val=%x)\n", port, *(char*)src);
-int read_data_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
+static int read_data_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
struct serial_state * state = (struct serial_state *)dev->private_data;
char * val = (char *)dst;
PrintDebug("Read from Data Port 0x%x\n", port);
-int handle_ier_write(struct serial_port * com, struct irq_enable_reg * ier) {
+static int handle_ier_write(struct serial_port * com, struct irq_enable_reg * ier) {
return -1;
}
-int write_ctrl_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int write_ctrl_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
struct serial_state * state = (struct serial_state *)dev->private_data;
char * val = (char *)src;
PrintDebug("Write to Control Port (val=%x)\n", *(char *)src);
-int read_ctrl_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
+static int read_ctrl_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
struct serial_state * state = (struct serial_state *)dev->private_data;
char * val = (char *)dst;
PrintDebug("Read from Control Port\n");
}
-int write_status_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int write_status_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
PrintDebug("Write to Status Port 0x%x (val=%x)\n", port, *(char *)src);
return -1;
}
-int read_status_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
+static int read_status_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
struct serial_state * state = (struct serial_state *)dev->private_data;
char * val = (char *)dst;
PrintDebug("Read from Status Port 0x%x\n", port);
return 0;
}
-int serial_init(struct vm_device * dev) {
+static int serial_init(struct vm_device * dev) {
struct serial_state * state = (struct serial_state *)dev->private_data;
}
-int serial_deinit(struct vm_device * dev) {
+static int serial_deinit(struct vm_device * dev) {
dev_unhook_io(dev, COM1_DATA_PORT);
#include <devices/generic.h>
#include <devices/ramdisk.h>
#include <devices/cdrom.h>
+#include <devices/bochs_debug.h>
#include <palacios/vmm_host_events.h>
}
-/*static int IO_Read(ushort_t port, void * dst, uint_t length, void * priv_data) {
-
- struct guest_info * info = priv_data;
- ulong_t tsc_spread = 0;
- ullong_t exit_tsc = 0;
-
-
- *(ulong_t *)(&exit_tsc) = info->vm_regs.rbx;
- *(ulong_t *)((&exit_tsc) + 4) = info->vm_regs.rcx;
- tsc_spread = info->exit_tsc - exit_tsc;
-
- PrintError("IOREAD tsc diff = %lu\n",tsc_spread);
- info->rip += 3;
-
-
- return 1;
-}
-*/
-
-
-
int config_guest(struct guest_info * info, struct v3_vm_config * config_ptr) {
struct vm_device * pic = create_pic();
struct vm_device * keyboard = create_keyboard();
struct vm_device * pit = create_pit();
+ struct vm_device * bochs_debug = create_bochs_debug();
//struct vm_device * serial = create_serial();
struct vm_device * generic = NULL;
v3_attach_device(info, pit);
v3_attach_device(info, keyboard);
// v3_attach_device(info, serial);
+ v3_attach_device(info, bochs_debug);
if (use_ramdisk) {
v3_attach_device(info, ramdisk);