From: Jack Lange Date: Fri, 18 Apr 2008 22:29:32 +0000 (+0000) Subject: added irq initial setup X-Git-Tag: working-cdboot-physical-but-not-qemu~15 X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=28b1d0ae6db40cb3e1f5a9b3596b625d2f2af0e4 added irq initial setup --- diff --git a/palacios/build/Makefile b/palacios/build/Makefile index 41e5652..416b0c7 100644 --- a/palacios/build/Makefile +++ b/palacios/build/Makefile @@ -1,6 +1,6 @@ # Makefile for GeekOS kernel, userspace, and tools # Copyright (c) 2004,2005 David H. Hovemeyer -# $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". @@ -134,7 +134,7 @@ VMM_C_OBJS := $(VMM_C_SRCS:%.c=palacios/%.o) 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) diff --git a/palacios/build/depend.mak b/palacios/build/depend.mak index d938c10..578c788 100644 --- a/palacios/build/depend.mak +++ b/palacios/build/depend.mak @@ -256,7 +256,13 @@ geekos/vmm_stubs.o: ../src/geekos/vmm_stubs.c ../include/geekos/vmm_stubs.h \ ../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 \ @@ -278,7 +284,7 @@ geekos/vm.o: ../src/geekos/vm.c ../include/geekos/vmm_stubs.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 \ @@ -296,7 +302,7 @@ geekos/main.o: ../src/geekos/main.c ../include/geekos/bootinfo.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 \ @@ -460,16 +466,7 @@ palacios/vmm_intr.o: ../src/palacios/vmm_intr.c ../include/palacios/vmm_intr.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 \ @@ -526,3 +523,22 @@ devices/nvram.o: ../src/devices/nvram.c ../include/devices/nvram.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 diff --git a/palacios/include/geekos/irq.h b/palacios/include/geekos/irq.h index 3164170..69e625c 100644 --- a/palacios/include/geekos/irq.h +++ b/palacios/include/geekos/irq.h @@ -1,7 +1,7 @@ /* * This is the device-driver interface to the interrupt system. * Copyright (c) 2001,2003 David H. Hovemeyer - * $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". @@ -23,6 +23,7 @@ void Disable_IRQ(int irq); * 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 */ diff --git a/palacios/include/geekos/vmm_stubs.h b/palacios/include/geekos/vmm_stubs.h index d6a8441..5a4b4cb 100644 --- a/palacios/include/geekos/vmm_stubs.h +++ b/palacios/include/geekos/vmm_stubs.h @@ -6,6 +6,8 @@ #include +struct guest_info; + void * Allocate_VMM_Pages(int num_pages); void Free_VMM_Page(void * page); @@ -14,6 +16,9 @@ void VMM_Free(void * addr); 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 diff --git a/palacios/include/palacios/vm_guest.h b/palacios/include/palacios/vm_guest.h index 8e8c6a5..cd2ce37 100644 --- a/palacios/include/palacios/vm_guest.h +++ b/palacios/include/palacios/vm_guest.h @@ -38,6 +38,12 @@ struct guest_gprs { 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; @@ -57,7 +63,7 @@ struct guest_info { 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 @@ -68,10 +74,13 @@ struct guest_info { struct guest_gprs vm_regs; + struct vm_ctrl_ops vm_ops; + void * vmm_data; }; + #endif diff --git a/palacios/include/palacios/vmm.h b/palacios/include/palacios/vmm.h index 746faba..df22134 100644 --- a/palacios/include/palacios/vmm.h +++ b/palacios/include/palacios/vmm.h @@ -85,6 +85,9 @@ struct vmm_os_hooks { 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, ...); @@ -98,10 +101,12 @@ struct vmm_ctrl_ops { 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); diff --git a/palacios/include/palacios/vmm_dev_mgr.h b/palacios/include/palacios/vmm_dev_mgr.h index 0caef8b..080de99 100644 --- a/palacios/include/palacios/vmm_dev_mgr.h +++ b/palacios/include/palacios/vmm_dev_mgr.h @@ -18,9 +18,10 @@ struct vmm_dev_mgr { uint_t num_mem_hooks; struct list_head mem_hooks; - + /* uint_t num_irq_hooks; struct list_head irq_hooks; + */ }; @@ -53,6 +54,7 @@ struct dev_mem_hook { struct list_head mgr_list; }; +/* struct dev_irq_hook { uint_t irq; @@ -64,6 +66,7 @@ struct dev_irq_hook { struct list_head mgr_list; }; +*/ // Registration of devices // diff --git a/palacios/include/palacios/vmm_intr.h b/palacios/include/palacios/vmm_intr.h index 108c27c..2f3596d 100644 --- a/palacios/include/palacios/vmm_intr.h +++ b/palacios/include/palacios/vmm_intr.h @@ -34,12 +34,27 @@ struct vm_intr { 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); diff --git a/palacios/src/geekos/irq.c b/palacios/src/geekos/irq.c index 24c5104..a98c3ad 100644 --- a/palacios/src/geekos/irq.c +++ b/palacios/src/geekos/irq.c @@ -1,7 +1,7 @@ /* * This is the device-driver interface to the interrupt system. * Copyright (c) 2001,2003 David H. Hovemeyer - * $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". @@ -119,6 +119,11 @@ void Begin_IRQ(struct Interrupt_State* state) 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) { diff --git a/palacios/src/geekos/main.c b/palacios/src/geekos/main.c index a66c42f..fed6908 100644 --- a/palacios/src/geekos/main.c +++ b/palacios/src/geekos/main.c @@ -3,7 +3,7 @@ * Copyright (c) 2001,2003,2004 David H. Hovemeyer * Copyright (c) 2003, Jeffrey K. Hollingsworth * Copyright (c) 2004, Iulian Neamtiu - * $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". @@ -34,6 +34,8 @@ #include #include +#include + @@ -190,6 +192,7 @@ void Main(struct Boot_Info* bootInfo) Init_Keyboard(); Init_VM(bootInfo); Init_Paging(); + Init_Stubs(); // Init_IDE(); diff --git a/palacios/src/geekos/vm.c b/palacios/src/geekos/vm.c index 1005507..4375e43 100644 --- a/palacios/src/geekos/vm.c +++ b/palacios/src/geekos/vm.c @@ -7,6 +7,9 @@ #include #include #include +#include +#include + #define SPEAKER_PORT 0x61 @@ -157,6 +160,8 @@ int RunVMM(struct Boot_Info * bootInfo) { 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)); @@ -181,9 +186,9 @@ int RunVMM(struct Boot_Info * bootInfo) { 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)); @@ -270,6 +275,7 @@ int RunVMM(struct Boot_Info * bootInfo) { 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); @@ -286,12 +292,14 @@ int RunVMM(struct Boot_Info * bootInfo) { 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)); @@ -299,6 +307,8 @@ int RunVMM(struct Boot_Info * bootInfo) { } + hook_irq(&vm_info, 6); + vm_info.rip = 0xfff0; vm_info.vm_regs.rsp = 0x0; } diff --git a/palacios/src/geekos/vmm_stubs.c b/palacios/src/geekos/vmm_stubs.c index 0bc48e3..c6b76cb 100644 --- a/palacios/src/geekos/vmm_stubs.c +++ b/palacios/src/geekos/vmm_stubs.c @@ -1,6 +1,6 @@ #include #include - +#include void * Identity(void *addr) { return addr; }; @@ -44,3 +44,41 @@ void * VMM_Malloc(unsigned int size) { 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); + +} diff --git a/palacios/src/palacios/svm.c b/palacios/src/palacios/svm.c index 077e95c..ff61e57 100644 --- a/palacios/src/palacios/svm.c +++ b/palacios/src/palacios/svm.c @@ -309,6 +309,7 @@ void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info vm_info) { 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; diff --git a/palacios/src/palacios/svm_handler.c b/palacios/src/palacios/svm_handler.c index a2e7e14..8ca0e50 100644 --- a/palacios/src/palacios/svm_handler.c +++ b/palacios/src/palacios/svm_handler.c @@ -79,6 +79,10 @@ int handle_svm_exit(struct guest_info * info) { } 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]; diff --git a/palacios/src/palacios/vmm.c b/palacios/src/palacios/vmm.c index 5a3eb04..7ae2239 100644 --- a/palacios/src/palacios/vmm.c +++ b/palacios/src/palacios/vmm.c @@ -1,7 +1,7 @@ #include #include #include - +#include uint_t vmm_cpu_type; @@ -12,13 +12,13 @@ struct vmm_os_hooks * os_hooks = NULL; + 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"); diff --git a/palacios/src/palacios/vmm_dev_mgr.c b/palacios/src/palacios/vmm_dev_mgr.c index 8652209..2a458d0 100644 --- a/palacios/src/palacios/vmm_dev_mgr.c +++ b/palacios/src/palacios/vmm_dev_mgr.c @@ -162,7 +162,7 @@ int dev_unhook_io(struct vm_device *dev, /* 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++; @@ -267,7 +267,7 @@ int dev_unhook_irq(struct vm_device * dev, } - +*/ diff --git a/palacios/src/palacios/vmm_intr.c b/palacios/src/palacios/vmm_intr.c index 657ddef..1e59299 100644 --- a/palacios/src/palacios/vmm_intr.c +++ b/palacios/src/palacios/vmm_intr.c @@ -1,15 +1,23 @@ #include - +#include #include -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, @@ -26,9 +34,19 @@ int raise_exception(struct guest_info * info, uint_t excp) { } +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 */ @@ -40,7 +58,9 @@ int intr_pending(struct vm_intr * intr) { 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 */ @@ -51,7 +71,15 @@ uint_t get_intr_number(struct vm_intr * 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); +}