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 <geekos/vmm_stubs.h>
24 #include <geekos/debug.h>
25 #include <geekos/serial.h>
26 #include <geekos/vm.h>
27 #include <geekos/screen.h>
29 #include <palacios/vmm.h>
30 #include <palacios/vmm_io.h>
34 extern void * g_ramdiskImage;
35 extern ulong_t s_ramdiskSize;
38 #define SPEAKER_PORT 0x61
40 static inline void VM_Out_Byte(ushort_t port, uchar_t value)
42 __asm__ __volatile__ (
45 : "a" (value), "Nd" (port)
50 * Read a byte from an I/O port.
52 static inline uchar_t VM_In_Byte(ushort_t port)
56 __asm__ __volatile__ (
68 int IO_Read(ushort_t port, void * dst, uint_t length, void * priv_data) {
74 *(uchar_t*)dst = VM_In_Byte(port);
80 int IO_Write(ushort_t port, void * src, uint_t length, void * priv_data) {
86 VM_Out_Byte(port, *(uchar_t *)src);
92 int IO_Read_to_Serial(ushort_t port, void * dst, uint_t length, void * priv_data) {
93 PrintBoth("Input from Guest on port %d (0x%x) Length=%d\n", port, port, length);
99 char * bochs_debug_buf = NULL;
100 int bochs_debug_offset = 0;
102 char * bochs_info_buf = NULL;
103 int bochs_info_offset = 0;
106 int IO_BOCHS_debug(ushort_t port, void * src, uint_t length, void * priv_data) {
107 if (!bochs_debug_buf) {
108 bochs_debug_buf = (char*)Malloc(1024);
111 bochs_debug_buf[bochs_debug_offset++] = *(char*)src;
113 if ((*(char*)src == 0xa) || (bochs_debug_offset == 1023)) {
114 SerialPrint("BOCHSDEBUG>%s", bochs_debug_buf);
115 memset(bochs_debug_buf, 0, 1024);
116 bochs_debug_offset = 0;
122 int IO_BOCHS_info(ushort_t port, void * src, uint_t length, void * priv_data) {
123 if (!bochs_info_buf) {
124 bochs_info_buf = (char*)Malloc(1024);
127 bochs_info_buf[bochs_info_offset++] = *(char*)src;
129 if ((*(char*)src == 0xa) || (bochs_info_offset == 1023)) {
130 SerialPrint("BOCHSINFO>%s", bochs_info_buf);
131 memset(bochs_info_buf, 0, 1024);
132 bochs_info_offset = 0;
139 int IO_Write_to_Serial(ushort_t port, void * src, uint_t length, void * priv_data) {
140 SerialPrint("Output from Guest on port %d (0x%x) Length=%d\n", port, port, length);
144 SerialPrint(">0x%.2x\n", *(char*)src);
147 SerialPrint(">0x%.4x\n", *(ushort_t*)src);
150 SerialPrint(">0x%.8x\n", *(uint_t*)src);
156 // SerialMemDump(src, length);
169 __asm__ __volatile__ (
175 PrintBoth("Starting To Buzz\n");
177 init=VM_In_Byte(SPEAKER_PORT);
180 VM_Out_Byte(SPEAKER_PORT, init|0x2);
181 for (j=0;j<1000000;j++) {
184 VM_Out_Byte(SPEAKER_PORT, init);
185 for (j=0;j<1000000;j++) {
193 int passthrough_mem_read(void * guest_addr, void * dst, uint_t length, void * priv_data) {
194 memcpy(dst, (void*)guest_addr, length);
198 int passthrough_mem_write(void * guest_addr, void * src, uint_t length, void * priv_data) {
199 memcpy((void*)guest_addr, src, length);
205 /* We need a configuration mechanism, so we can wrap this completely inside the VMM code,
206 * with no pollution into the HOST OS
209 int RunVMM(struct Boot_Info * bootInfo) {
210 struct vmm_os_hooks os_hooks;
211 struct vmm_ctrl_ops vmm_ops;
212 struct guest_info * vm_info = 0;
213 struct v3_vm_config vm_config;
217 memset(&os_hooks, 0, sizeof(struct vmm_os_hooks));
218 memset(&vmm_ops, 0, sizeof(struct vmm_ctrl_ops));
219 memset(&vm_config, 0, sizeof(struct v3_vm_config));
222 os_hooks.print_debug = &SerialPrint;
223 os_hooks.print_info = &Print;
224 os_hooks.print_trace = &SerialPrint;
225 os_hooks.allocate_pages = &Allocate_VMM_Pages;
226 os_hooks.free_page = &Free_VMM_Page;
227 os_hooks.malloc = &VMM_Malloc;
228 os_hooks.free = &VMM_Free;
229 os_hooks.vaddr_to_paddr = &Identity;
230 os_hooks.paddr_to_vaddr = &Identity;
231 os_hooks.hook_interrupt = &geekos_hook_interrupt_new;
232 os_hooks.ack_irq = &ack_irq;
233 os_hooks.get_cpu_khz = &get_cpu_khz;
237 Init_V3(&os_hooks, &vmm_ops);
240 extern char _binary___palacios_vm_kernel_start;
241 PrintBoth(" Guest Load Addr: 0x%x\n", &_binary___palacios_vm_kernel_start);
243 vm_config.vm_kernel = &_binary___palacios_vm_kernel_start;
246 if (g_ramdiskImage != NULL) {
247 vm_config.use_ramdisk = 1;
248 vm_config.ramdisk = g_ramdiskImage;
249 vm_config.ramdisk_size = s_ramdiskSize;
255 vm_info = (vmm_ops).allocate_guest();
257 PrintBoth("Allocated Guest\n");
259 (vmm_ops).config_guest(vm_info, &vm_config);
261 PrintBoth("Configured guest\n");
264 //v3_hook_io_port(&vm_info, 0x05, &IO_Read, &IO_Write_to_Serial, NULL);
266 //v3_hook_io_port(vm_info, 0x61, &IO_Read, &IO_Write, NULL);
267 //v3_hook_io_port(vm_info, 0x400, &IO_Read, &IO_Write_to_Serial, NULL);
268 //v3_hook_io_port(vm_info, 0x401, &IO_Read, &IO_Write_to_Serial, NULL);
269 //v3_hook_io_port(vm_info, 0x402, &IO_Read, &IO_BOCHS_info, NULL);
270 //v3_hook_io_port(vm_info, 0x403, &IO_Read, &IO_BOCHS_debug, NULL);
273 (vmm_ops).init_guest(vm_info);
274 PrintBoth("Starting Guest\n");
276 (vmm_ops).start_guest(vm_info);