# Makefile for GeekOS kernel, userspace, and tools
# Copyright (c) 2004,2005 David H. Hovemeyer <daveho@cs.umd.edu>
-# $Revision: 1.26 $
+# $Revision: 1.27 $
# This is free software. You are permitted to use,
# redistribute, and modify it as specified in the file "COPYING".
VMM_OBJS := $(VMM_C_OBJS) $(VMM_ASM_OBJS)
-DEVICE_C_SRCS := nvram.c timer.c
+DEVICE_C_SRCS := nvram.c timer.c simple_pic.c
DEVICE_C_OBJS := $(DEVICE_C_SRCS:%.c=devices/%.o)
../include/geekos/irq.h ../include/geekos/int.h \
../include/geekos/string.h ../include/geekos/../libc/string.h \
/home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
- ../include/geekos/io.h
+ ../include/geekos/io.h ../include/palacios/vm_guest.h \
+ ../include/palacios/vmm_mem.h ../include/palacios/vmm_types.h \
+ ../include/palacios/vmm_io.h ../include/palacios/vmm_util.h \
+ ../include/palacios/vmm_shadow_paging.h \
+ ../include/palacios/vmm_paging.h ../include/palacios/vmm_intr.h \
+ ../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_list.h \
+ ../include/palacios/vmm_string.h ../include/palacios/vmm_irq.h
geekos/vm.o: ../src/geekos/vm.c ../include/geekos/vmm_stubs.h \
../include/geekos/mem.h ../include/geekos/ktypes.h \
/home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
../include/geekos/int.h ../include/geekos/string.h \
../include/geekos/../libc/string.h ../include/geekos/io.h \
../include/geekos/vm.h ../include/devices/nvram.h \
- ../include/palacios/vm_dev.h
+ ../include/palacios/vm_dev.h ../include/devices/timer.h
geekos/main.o: ../src/geekos/main.c ../include/geekos/bootinfo.h \
../include/geekos/string.h ../include/geekos/../libc/string.h \
/home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
../include/geekos/irq.h ../include/geekos/reboot.h \
../include/geekos/ide.h ../include/geekos/malloc.h \
../include/geekos/debug.h ../include/geekos/vm.h \
- ../include/geekos/gdt.h
+ ../include/geekos/gdt.h ../include/geekos/vmm_stubs.h
common/fmtout.o: ../src/common/fmtout.c \
/home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
/home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
../include/palacios/vmm_list.h ../include/palacios/vmm_string.h \
/home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
../include/palacios/vmm_irq.h
-palacios/vmm_irq.o: ../src/palacios/vmm_irq.c ../include/palacios/vmm_irq.h \
- ../include/palacios/vmm_types.h ../include/geekos/ktypes.h \
- /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
- ../include/palacios/vmm.h ../include/palacios/vmm_string.h \
- /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
- ../include/palacios/vmm_mem.h ../include/palacios/vm_guest.h \
- ../include/palacios/vmm_io.h ../include/palacios/vmm_util.h \
- ../include/palacios/vmm_shadow_paging.h \
- ../include/palacios/vmm_paging.h ../include/palacios/vmm_intr.h \
- ../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_list.h
+palacios/vmm_irq.o: ../src/palacios/vmm_irq.c
palacios/vmm_shadow_paging.o: ../src/palacios/vmm_shadow_paging.c \
../include/palacios/vmm_shadow_paging.h ../include/palacios/vmm_util.h \
../include/palacios/vmm_types.h ../include/geekos/ktypes.h \
../include/palacios/vmm_shadow_paging.h \
../include/palacios/vmm_paging.h ../include/palacios/vmm_intr.h \
../include/palacios/vmm_irq.h
+devices/timer.o: ../src/devices/timer.c ../include/devices/timer.h \
+ ../include/palacios/vm_dev.h ../include/palacios/vmm_types.h \
+ ../include/geekos/ktypes.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+ ../include/palacios/vmm_list.h ../include/palacios/vmm_string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm.h \
+ ../include/palacios/vmm_mem.h ../include/palacios/vm_guest.h \
+ ../include/palacios/vmm_io.h ../include/palacios/vmm_util.h \
+ ../include/palacios/vmm_shadow_paging.h \
+ ../include/palacios/vmm_paging.h ../include/palacios/vmm_intr.h \
+ ../include/palacios/vmm_irq.h
+devices/simple_pic.o: ../src/devices/simple_pic.c ../include/devices/simple_pic.h \
+ ../include/palacios/vm_dev.h ../include/palacios/vmm_types.h \
+ ../include/geekos/ktypes.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+ ../include/palacios/vmm_list.h ../include/palacios/vmm_string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_intr.h
/*
* This is the device-driver interface to the interrupt system.
* Copyright (c) 2001,2003 David H. Hovemeyer <daveho@cs.umd.edu>
- * $Revision: 1.1 $
+ * $Revision: 1.2 $
*
* This is free software. You are permitted to use,
* redistribute, and modify it as specified in the file "COPYING".
* interrupt.
*/
void Begin_IRQ(struct Interrupt_State* state);
+void End_IRQ_num(int irq);
void End_IRQ(struct Interrupt_State* state);
#endif /* GEEKOS_IRQ_H */
#include <geekos/malloc.h>
+struct guest_info;
+
void * Allocate_VMM_Pages(int num_pages);
void Free_VMM_Page(void * page);
void * Identity(void *addr);
-void Hook_IRQ(int irq, void (*handler)());
+int hook_irq_stub(struct guest_info * info, int irq);
+int ack_irq(int irq);
+
+void Init_Stubs();
#endif
struct shadow_page_state;
struct shadow_map;
+
+struct vm_ctrl_ops {
+ int (*raise_irq)(struct guest_info * info, int irq, int error_code);
+};
+
+
typedef enum {SHADOW_PAGING, NESTED_PAGING} vm_page_mode_t;
typedef enum {REAL, PROTECTED, PROTECTED_PG, PROTECTED_PAE, PROTECTED_PAE_PG, LONG, LONG_PG} vm_cpu_mode_t;
struct vm_intr intr_state;
- struct vmm_irq_map irq_map;
+ // struct vmm_irq_map irq_map;
vmm_io_map_t io_map;
// device_map
struct guest_gprs vm_regs;
+ struct vm_ctrl_ops vm_ops;
+
void * vmm_data;
};
+
#endif
void *(*paddr_to_vaddr)(void *addr);
void *(*vaddr_to_paddr)(void *addr);
+ int (*hook_interrupt)(struct guest_info * info, int irq);
+ int (*ack_irq)(int irq);
+
// Do we need this here?
void (*snprintf)(char * dst, char * format, int len, ...);
int (*init_guest)(struct guest_info* info);
int (*start_guest)(struct guest_info * info);
// int (*stop_vm)(uint_t vm_id);
-};
+};
+
+
void Init_VMM(struct vmm_os_hooks * hooks, struct vmm_ctrl_ops * vmm_ops);
uint_t num_mem_hooks;
struct list_head mem_hooks;
-
+ /*
uint_t num_irq_hooks;
struct list_head irq_hooks;
+ */
};
struct list_head mgr_list;
};
+/*
struct dev_irq_hook {
uint_t irq;
struct list_head mgr_list;
};
+*/
// Registration of devices
//
uint_t excp_num;
uint_t excp_error_code;
+ struct intr_ctrl_ops * controller;
+ void * controller_state;
+
/* some way to get the [A]PIC intr */
};
-void init_interrupt_state(struct vm_intr * state);
+int raise_irq(struct guest_info * info, int irq, int error_code);
+int hook_irq(struct guest_info * info, int irq);
+
+struct intr_ctrl_ops {
+ int (*intr_pending)(void * private_data);
+ int (*get_intr_number)(void * private_data);
+ int (*raise_intr)(void * private_data, int irq, int error_code);
+};
+
+
+
+void init_interrupt_state(struct guest_info * info);
+void set_intr_controller(struct guest_info * info, struct intr_ctrl_ops * ops, void * state);
int raise_exception(struct guest_info * info, uint_t excp);
/*
* This is the device-driver interface to the interrupt system.
* Copyright (c) 2001,2003 David H. Hovemeyer <daveho@cs.umd.edu>
- * $Revision: 1.1 $
+ * $Revision: 1.2 $
*
* This is free software. You are permitted to use,
* redistribute, and modify it as specified in the file "COPYING".
void End_IRQ(struct Interrupt_State* state)
{
int irq = state->intNum - FIRST_EXTERNAL_INT;
+ End_IRQ_num(irq);
+}
+
+
+void End_IRQ_num(int irq) {
uchar_t command = 0x60 | (irq & 0x7);
if (irq < 8) {
* Copyright (c) 2001,2003,2004 David H. Hovemeyer <daveho@cs.umd.edu>
* Copyright (c) 2003, Jeffrey K. Hollingsworth <hollings@cs.umd.edu>
* Copyright (c) 2004, Iulian Neamtiu <neamtiu@cs.umd.edu>
- * $Revision: 1.33 $
+ * $Revision: 1.34 $
*
* This is free software. You are permitted to use,
* redistribute, and modify it as specified in the file "COPYING".
#include <geekos/vm.h>
#include <geekos/gdt.h>
+#include <geekos/vmm_stubs.h>
+
Init_Keyboard();
Init_VM(bootInfo);
Init_Paging();
+ Init_Stubs();
// Init_IDE();
#include <palacios/vmm_dev_mgr.h>
#include <devices/nvram.h>
#include <devices/timer.h>
+#include <devices/simple_pic.h>
+#include <palacios/vmm_intr.h>
+
#define SPEAKER_PORT 0x61
addr_t rsp;
addr_t rip;
+
+
memset(&os_hooks, 0, sizeof(struct vmm_os_hooks));
memset(&vmm_ops, 0, sizeof(struct vmm_ctrl_ops));
memset(&vm_info, 0, sizeof(struct guest_info));
vm_info.cpu_mode = REAL;
- init_irq_map(&(vm_info.irq_map));
+ //init_irq_map(&(vm_info.irq_map));
init_vmm_io_map(&(vm_info.io_map));
- init_interrupt_state(&(vm_info.intr_state));
+ init_interrupt_state(&vm_info);
dev_mgr_init(&(vm_info.dev_mgr));
PrintDebug("Error adding shadow region\n");
}
+
print_shadow_map(&(vm_info.mem_map));
hook_io_port(&(vm_info.io_map), 0x61, &IO_Read, &IO_Write, NULL);
hook_io_port(&(vm_info.io_map), 0x403, &IO_Read, &IO_Write_to_Serial, NULL);
{
- struct vm_device * nvram = create_nvram();
+ //struct vm_device * nvram = create_nvram();
//struct vm_device * timer = create_timer();
+ struct vm_device * pic = create_pic();
- attach_device(&(vm_info), nvram);
+ //attach_device(&(vm_info), nvram);
//attach_device(&(vm_info), timer);
-
+ attach_device(&(vm_info), pic);
+
PrintDebugDevMgr(&(vm_info.dev_mgr));
}
+ hook_irq(&vm_info, 6);
+
vm_info.rip = 0xfff0;
vm_info.vm_regs.rsp = 0x0;
}
#include <geekos/vmm_stubs.h>
#include <geekos/serial.h>
-
+#include <palacios/vm_guest.h>
void * Identity(void *addr) { return addr; };
void VMM_Free(void * addr) {
Free(addr);
}
+
+
+
+
+struct guest_info * irq_map[256];
+
+
+static void pic_intr_handler(struct Interrupt_State * state) {
+ Begin_IRQ(state);
+
+ irq_map[state->intNum]->vm_ops.raise_irq(irq_map[state->intNum], state->intNum, state->errorCode);
+
+ // End_IRQ(state);
+}
+
+
+int hook_irq_stub(struct guest_info * info, int irq) {
+ if (irq_map[irq]) {
+ return -1;
+ }
+
+ irq_map[irq] = info;
+ Install_IRQ(irq, pic_intr_handler);
+ Enable_IRQ(irq);
+ return 0;
+}
+
+
+int ack_irq(int irq) {
+ End_IRQ_num(irq);
+ return 0;
+}
+
+
+void Init_Stubs() {
+ memset(irq_map, 0, sizeof(struct guest_info *) * 256);
+
+}
guest_state->efer |= EFER_MSR_svm_enable;
guest_state->rflags = 0x00000002; // The reserved bit is always 1
ctrl_area->svm_instrs.VMRUN = 1;
+ ctrl_area->instrs.HLT = 1;
// guest_state->cr0 = 0x00000001; // PE
ctrl_area->guest_ASID = 1;
} else if (exit_code == VMEXIT_INTR) {
// handle_svm_intr(info);
+
+ } else if (exit_code == VMEXIT_HLT) {
+ PrintDebug("Guest halted\n");
+ return -1;
} else {
addr_t rip_addr = get_addr_linear(info, guest_state->rip, guest_state->cs.selector);
char buf[15];
#include <palacios/vmm.h>
#include <palacios/svm.h>
#include <palacios/vmx.h>
-
+#include <palacios/vmm_intr.h>
uint_t vmm_cpu_type;
+
void Init_VMM(struct vmm_os_hooks * hooks, struct vmm_ctrl_ops * vmm_ops) {
vmm_cpu_type = VMM_INVALID_CPU;
os_hooks = hooks;
-
if (is_svm_capable()) {
vmm_cpu_type = VMM_SVM_CPU;
PrintDebug("Machine is SVM Capable\n");
/* IRQ HOOKS */
-
+/*
int dev_mgr_add_irq_hook(struct vmm_dev_mgr * mgr, struct dev_irq_hook * hook) {
list_add(&(hook->mgr_list), &(mgr->irq_hooks));
mgr->num_irq_hooks++;
}
-
+*/
#include <palacios/vmm_intr.h>
-
+#include <palacios/vmm.h>
#include <palacios/vm_guest.h>
-void init_interrupt_state(struct vm_intr * state) {
- state->excp_pending = 0;
- state->excp_num = 0;
- state->excp_error_code = 0;
+void init_interrupt_state(struct guest_info * info) {
+ info->intr_state.excp_pending = 0;
+ info->intr_state.excp_num = 0;
+ info->intr_state.excp_error_code = 0;
+
+ info->vm_ops.raise_irq = &raise_irq;
+}
+
+void set_intr_controller(struct guest_info * info, struct intr_ctrl_ops * ops, void * state) {
+ info->intr_state.controller = ops;
+ info->intr_state.controller_state = state;
}
+
int raise_exception(struct guest_info * info, uint_t excp) {
/* We can't stack exceptions,
}
+int raise_irq(struct guest_info * info, int irq, int error_code) {
+ // Look up PIC and resend
+ info->intr_state.controller->raise_intr(info->intr_state.controller_state, irq, error_code);
+
+ return 0;
+}
+
+
int intr_pending(struct vm_intr * intr) {
if (intr->excp_pending) {
return 1;
+ } else if (intr->controller->intr_pending(intr->controller_state)) {
+ return 1;
}
/* Check [A]PIC */
uint_t get_intr_number(struct vm_intr * intr) {
if (intr->excp_pending) {
return intr->excp_num;
- }
+ } else if (intr->controller->intr_pending(intr->controller_state)) {
+ return intr->controller->get_intr_number(intr->controller_state) + 32;
+ }
/* someway to get the [A]PIC intr */
uint_t get_intr_type(struct vm_intr * intr) {
if (intr->excp_pending) {
return EXCEPTION;
+ } else if (intr->controller->intr_pending(intr->controller_state)) {
+ return EXTERNAL_IRQ;
}
return INVALID_INTR;
}
+
+int hook_irq(struct guest_info * info, int irq) {
+ extern struct vmm_os_hooks * os_hooks;
+
+ return os_hooks->hook_interrupt(info, irq);
+}