From: Jack Lange Date: Sat, 25 Jul 2009 05:31:08 +0000 (-0500) Subject: Update to the device framework. X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=37c18b2c2335a41c68c2f0b779fd2b7d51ab216d Update to the device framework. This creates a global device registration space, that is used to create a hash table of all available devices. A guest can instantiate and configure a device based on a hash of the device name. This should make guest configuration much more straight forward. --- diff --git a/palacios/build/Makefile b/palacios/build/Makefile index 6acfc6a..9b50e6c 100644 --- a/palacios/build/Makefile +++ b/palacios/build/Makefile @@ -284,7 +284,6 @@ VMM_OBJS := \ palacios/vmm_time.o \ palacios/vmm_shadow_paging.o \ palacios/vm_guest_mem.o \ - palacios/vm_dev.o \ palacios/vmm_dev_mgr.o \ palacios/vmm_decoder.o \ palacios/svm_halt.o \ @@ -589,6 +588,7 @@ clean : for d in palacios devices xed; do \ (cd $$d && rm -f * .*.d); \ done + rm -f libv3vee.a # Include all of the generated dependency files if they exist diff --git a/palacios/include/devices/8237_dma.h b/palacios/include/devices/8237_dma.h deleted file mode 100644 index e57922d..0000000 --- a/palacios/include/devices/8237_dma.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Jack Lange - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - - -#ifndef __DEVICES_8237_DMA_H__ -#define __DEVICES_8237_DMA_H__ - -#ifdef __V3VEE__ - - -#include - -struct vm_device * v3_create_dma(); - - -#endif // ! __V3VEE__ - -#endif diff --git a/palacios/include/devices/8254.h b/palacios/include/devices/8254.h deleted file mode 100644 index c5efc0f..0000000 --- a/palacios/include/devices/8254.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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 - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Jack Lange - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - -#ifndef __DEVICES_8254_H__ -#define __DEVICES_8254_H__ - -#ifdef __V3VEE__ - - - -#include - -struct vm_device * v3_create_pit(); - - - -#endif // ! __V3VEE__ - -#endif diff --git a/palacios/include/devices/8259a.h b/palacios/include/devices/8259a.h deleted file mode 100644 index 3bc375b..0000000 --- a/palacios/include/devices/8259a.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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 - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Jack Lange - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - -#ifndef __DEVICES_8259A_H__ -#define __DEVICES_8259A_H__ - -#ifdef __V3VEE__ - - - -#include - -struct vm_device * v3_create_pic(); - - - -#endif // ! __V3VEE__ - -#endif diff --git a/palacios/include/devices/apic.h b/palacios/include/devices/apic.h index 2e4a0a8..5a11639 100644 --- a/palacios/include/devices/apic.h +++ b/palacios/include/devices/apic.h @@ -22,9 +22,7 @@ #ifdef __V3VEE__ -#include - -struct vm_device * v3_create_apic(); +#include int v3_apic_raise_intr(struct vm_device * apic_dev, int intr_num); diff --git a/palacios/include/devices/bochs_debug.h b/palacios/include/devices/bochs_debug.h deleted file mode 100644 index d441202..0000000 --- a/palacios/include/devices/bochs_debug.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Jack Lange - * - * 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 - -struct vm_device * v3_create_bochs_debug(); - - -#endif // ! __V3VEE__ - -#endif diff --git a/palacios/include/devices/generic.h b/palacios/include/devices/generic.h index 743a584..77d3822 100644 --- a/palacios/include/devices/generic.h +++ b/palacios/include/devices/generic.h @@ -25,10 +25,9 @@ #ifdef __V3VEE__ +#include -#include - // // The generic device simply hooks ranges of ports, addresses, and irqs // if they are not already hooked @@ -54,8 +53,7 @@ int v3_generic_add_port_range(struct vm_device * dev, uint_t start, uint_t end, uint_t type); -// The lists given are null terminated -struct vm_device * v3_create_generic(); + #endif // ! __V3VEE__ diff --git a/palacios/include/devices/i440fx.h b/palacios/include/devices/i440fx.h deleted file mode 100644 index 56bf619..0000000 --- a/palacios/include/devices/i440fx.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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 - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Jack Lange - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - -#ifndef __DEVICES_i440FX_H__ -#define __DEVICES_i440FX_H__ - -#ifdef __V3VEE__ - -#include - - -struct vm_device * v3_create_i440fx(struct vm_device * pci); - - -#endif - -#endif diff --git a/palacios/include/devices/ide.h b/palacios/include/devices/ide.h index d299827..88c593e 100644 --- a/palacios/include/devices/ide.h +++ b/palacios/include/devices/ide.h @@ -21,7 +21,12 @@ #define __DEVICES_IDE_H__ #ifdef __V3VEE__ -#include + + +struct ide_cfg { + char pci[32]; + char southbridge[32]; +}; #define ATAPI_BLOCK_SIZE 2048 @@ -60,8 +65,6 @@ int v3_ide_register_harddisk(struct vm_device * ide, -struct vm_device * v3_create_ide(); - int v3_ide_get_geometry(struct vm_device * ide_dev, int channel_num, int drive_num, diff --git a/palacios/include/devices/io_apic.h b/palacios/include/devices/io_apic.h deleted file mode 100644 index 5d9e9c1..0000000 --- a/palacios/include/devices/io_apic.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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 - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Jack Lange - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - -#ifndef __DEVICES_IO_APIC_H__ -#define __DEVICES_IO_APIC_H__ - - -#ifdef __V3VEE__ - -#include - - -struct vm_device * v3_create_io_apic(struct vm_device * apic); - - -#endif // ! __V3VEE__ -#endif diff --git a/palacios/include/devices/keyboard.h b/palacios/include/devices/keyboard.h deleted file mode 100644 index d2923be..0000000 --- a/palacios/include/devices/keyboard.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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, Peter Dinda - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Peter Dinda - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - -#ifndef __DEVICES_KEYBOARD_H__ -#define __DEVICES_KEYBOARD_H__ - -#ifdef __V3VEE__ - - - -#include - -struct vm_device * v3_create_keyboard(); - - - -#endif // ! __V3VEE__ - -#endif diff --git a/palacios/include/devices/lnx_virtio.h b/palacios/include/devices/lnx_virtio.h index e50a1d1..9afa483 100644 --- a/palacios/include/devices/lnx_virtio.h +++ b/palacios/include/devices/lnx_virtio.h @@ -23,7 +23,6 @@ #ifdef __V3VEE__ -#include /* PCI Vendor IDs (from Qemu) */ @@ -60,11 +59,6 @@ struct virtio_config { -struct vm_device * v3_create_virtio_blk(); - - - - diff --git a/palacios/include/devices/ne2k.h b/palacios/include/devices/ne2k.h deleted file mode 100644 index 17b9201..0000000 --- a/palacios/include/devices/ne2k.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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) 2009, Lei Xia - * Copyright (c) 2009, The V3VEE Project - * All rights reserved. - * - * Author: Lei Xia - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - -#ifndef __NE2K_H_ -#define __NE2K_H_ - -#include -#include - - -struct vm_device * v3_create_ne2k(); - -#endif diff --git a/palacios/include/devices/net_cd.h b/palacios/include/devices/net_cd.h index 05ed294..d1f8a31 100644 --- a/palacios/include/devices/net_cd.h +++ b/palacios/include/devices/net_cd.h @@ -22,13 +22,15 @@ #ifdef __V3VEE__ -#include - -struct vm_device * v3_create_net_cd(struct vm_device * ide, - uint_t bus, uint_t drive, - const char * ip_str, uint16_t port, - const char * disk_tag); +struct net_cd_cfg { + char ide[32]; + uint_t bus; + uint_t drive; + const char * ip_str; + uint16_t port; + const char * disk_tag; +}; diff --git a/palacios/include/devices/net_hd.h b/palacios/include/devices/net_hd.h index cf4471f..2a57832 100644 --- a/palacios/include/devices/net_hd.h +++ b/palacios/include/devices/net_hd.h @@ -22,13 +22,16 @@ #ifdef __V3VEE__ -#include -struct vm_device * v3_create_net_hd(struct vm_device * ide, - uint_t bus, uint_t drive, - const char * ip_str, uint16_t port, - const char * disk_tag); +struct net_hd_cfg { + char ide[32]; + uint_t bus; + uint_t drive; + const char * ip_str; + uint16_t port; + const char * disk_tag; +}; diff --git a/palacios/include/devices/nvram.h b/palacios/include/devices/nvram.h deleted file mode 100644 index 859fd86..0000000 --- a/palacios/include/devices/nvram.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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, Peter Dinda - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Peter Dinda - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - -#ifndef __DEVICES_NVRAM_H__ -#define __DEVICES_NVRAM_H__ - -#ifdef __V3VEE__ - - -#include - -struct vm_device * v3_create_nvram(struct vm_device * ide); - - - -#endif // ! __V3VEE__ - -#endif diff --git a/palacios/include/devices/os_debug.h b/palacios/include/devices/os_debug.h deleted file mode 100644 index 5434492..0000000 --- a/palacios/include/devices/os_debug.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Jack Lange - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - -#ifndef __DEVICES_OS_DEBUG_H__ -#define __DEVICES_OS_DEBUG_H__ - -#ifdef __V3VEE__ - -#include - -struct vm_device * v3_create_os_debug(); - - -#endif // ! __V3VEE__ - -#endif diff --git a/palacios/include/devices/para_net.h b/palacios/include/devices/para_net.h deleted file mode 100644 index 8e6c7fb..0000000 --- a/palacios/include/devices/para_net.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Jack Lange - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - -#ifndef __DEVICES_PARA_NET_H__ -#define __DEVICES_PARA_NET_H__ - -#ifdef __V3VEE__ - -#include - -struct vm_device * v3_create_para_net(); - - -#endif // ! __V3VEE__ - -#endif diff --git a/palacios/include/devices/pci.h b/palacios/include/devices/pci.h index 23bdae7..d80530a 100644 --- a/palacios/include/devices/pci.h +++ b/palacios/include/devices/pci.h @@ -24,7 +24,7 @@ #ifdef __V3VEE__ -#include + #include #include @@ -115,7 +115,7 @@ struct pci_device { -struct vm_device * v3_create_pci(); + struct pci_device * v3_pci_register_device(struct vm_device * pci, diff --git a/palacios/include/devices/piix3.h b/palacios/include/devices/piix3.h deleted file mode 100644 index db390a8..0000000 --- a/palacios/include/devices/piix3.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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) 2009, Lei Xia - * Copyright (c) 2009, Chang Seok Bae - * Copyright (c) 2009, Jack Lange - * Copyright (c) 2009, The V3VEE Project - * All rights reserved. - * - * Author: Lei Xia - * Chang Seok Bae - * Jack Lange - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - -#ifndef __DEVICES_PIIX3_H__ -#define __DEVICES_PIIX3_H__ - - -#ifdef __V3VEE__ - -#include - - -struct vm_device * v3_create_piix3(struct vm_device * pci); - -#endif // ! __V3VEE__ - -#endif diff --git a/palacios/include/devices/ram_cd.h b/palacios/include/devices/ram_cd.h index 34c90c2..c105394 100644 --- a/palacios/include/devices/ram_cd.h +++ b/palacios/include/devices/ram_cd.h @@ -22,12 +22,15 @@ #ifdef __V3VEE__ -#include -struct vm_device * v3_create_ram_cd(struct vm_device * ide, - uint_t bus, uint_t drive, - addr_t ramdisk, uint32_t size); +struct ram_cd_cfg { + char ide[32]; + uint_t bus; + uint_t drive; + addr_t ramdisk; + uint32_t size; +}; diff --git a/palacios/include/devices/ram_hd.h b/palacios/include/devices/ram_hd.h index 77adf3e..4c4fdad 100644 --- a/palacios/include/devices/ram_hd.h +++ b/palacios/include/devices/ram_hd.h @@ -22,12 +22,13 @@ #ifdef __V3VEE__ -#include - - -struct vm_device * v3_create_ram_hd(struct vm_device * ide, - uint_t bus, uint_t drive, - addr_t ramdisk, uint32_t size); +struct ram_hd_cfg { + char ide[32]; + uint_t bus; + uint_t drive; + addr_t ramdisk; + uint32_t size; +}; diff --git a/palacios/include/devices/serial.h b/palacios/include/devices/serial.h deleted file mode 100644 index f9be921..0000000 --- a/palacios/include/devices/serial.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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 - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Jack Lange - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - - -#ifndef __DEVICES_SERIAL_H__ -#define __DEVICES_SERIAL_H__ - -#ifdef __V3VEE__ - - - -#include - -struct vm_device * v3_create_serial(); - - - -#endif // ! __V3VEE__ - -#endif diff --git a/palacios/include/devices/simple_pic.h b/palacios/include/devices/simple_pic.h deleted file mode 100644 index 0a49b10..0000000 --- a/palacios/include/devices/simple_pic.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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 - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Jack Lange - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - -#ifndef __DEVICES_SIMPLE_PIC_H__ -#define __DEVICES_SIMPLE_PIC_H__ - -#ifdef __V3VEE__ - - -#include - -struct vm_device * v3_create_simple_pic(); - - -#endif // ! __V3VEE__ - -#endif diff --git a/palacios/include/devices/sym_swap.h b/palacios/include/devices/sym_swap.h deleted file mode 100644 index da66f20..0000000 --- a/palacios/include/devices/sym_swap.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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 - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Jack Lange - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - - - -#ifndef __DEVICES_SYM_SWAP_H__ -#define __DEVICES_SYM_SWAP_H__ - -#ifdef __V3VEE__ - -#include - - - -struct vm_device * v3_create_swap(struct vm_device * virtio_blk); - - - -#endif - -#endif diff --git a/palacios/include/devices/timer.h b/palacios/include/devices/timer.h deleted file mode 100644 index e38c307..0000000 --- a/palacios/include/devices/timer.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Jack Lange - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - -#ifndef __DEVICES_TIMER_H__ -#define __DEVICES_TIMER_H__ - -#ifdef __V3VEE__ - - -#include - -struct vm_device * v3_create_timer(); - - - -#endif // ! __V3VEE__ - -#endif diff --git a/palacios/include/palacios/vm_dev.h b/palacios/include/palacios/vm_dev.h deleted file mode 100644 index acac3f1..0000000 --- a/palacios/include/palacios/vm_dev.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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 - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Jack Lange - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - -#ifndef __VM_DEV_H -#define __VM_DEV_H - -#ifdef __V3VEE__ - -#include -#include -#include - -struct guest_info; - - -struct vm_device; - - -struct vm_device_ops { - int (*init)(struct vm_device *dev); - int (*deinit)(struct vm_device *dev); - - - int (*reset)(struct vm_device *dev); - - int (*start)(struct vm_device *dev); - int (*stop)(struct vm_device *dev); - - - //int (*save)(struct vm_device *dev, struct *iostream); - //int (*restore)(struct vm_device *dev, struct *iostream); -}; - - - -struct vm_device { - char name[32]; - - void *private_data; - - struct vm_device_ops * ops; - - struct guest_info * vm; - - struct list_head dev_link; - - - uint_t num_io_hooks; - struct list_head io_hooks; -}; - - - - -struct vm_device * v3_create_device(char * name, struct vm_device_ops * ops, void * private_data); -void v3_free_device(struct vm_device * dev); - - - -int v3_dev_hook_io(struct vm_device *dev, - ushort_t port, - int (*read)(ushort_t port, void * dst, uint_t length, struct vm_device * dev), - int (*write)(ushort_t port, void * src, uint_t length, struct vm_device * dev)); - -int v3_dev_unhook_io(struct vm_device *dev, - ushort_t port); - - - - - - -#endif // ! __V3VEE__ - -#endif diff --git a/palacios/include/palacios/vmm_dev_mgr.h b/palacios/include/palacios/vmm_dev_mgr.h index c3a5558..9495861 100644 --- a/palacios/include/palacios/vmm_dev_mgr.h +++ b/palacios/include/palacios/vmm_dev_mgr.h @@ -27,9 +27,29 @@ #include #include -struct vm_device; + struct guest_info; +struct v3_device_ops; + + +struct vm_device { + char name[32]; + + void * private_data; + + struct v3_device_ops * ops; + + struct guest_info * vm; + + struct list_head dev_link; + + + uint_t num_io_hooks; + struct list_head io_hooks; +}; + + struct vmm_dev_mgr { uint_t num_devs; struct list_head dev_list; @@ -39,6 +59,14 @@ struct vmm_dev_mgr { + +int v3_create_device(struct guest_info * info, const char * dev_name, void * cfg_data); +void v3_free_device(struct vm_device * dev); + + +struct vm_device * v3_find_dev(struct guest_info * info, const char * dev_name); + + // Registration of devices // @@ -46,16 +74,75 @@ struct vmm_dev_mgr { // when the guest is stopped // -int v3_attach_device(struct guest_info * vm, struct vm_device * dev); -int v3_detach_device(struct vm_device * dev); int v3_init_dev_mgr(struct guest_info * info); int v3_dev_mgr_deinit(struct guest_info * info); + + + +int v3_init_devices(); + + +struct v3_device_ops { + int (*free)(struct vm_device *dev); + + + int (*reset)(struct vm_device *dev); + + int (*start)(struct vm_device *dev); + int (*stop)(struct vm_device *dev); + + + //int (*save)(struct vm_device *dev, struct *iostream); + //int (*restore)(struct vm_device *dev, struct *iostream); +}; + + + + + + +int v3_dev_hook_io(struct vm_device *dev, + ushort_t port, + int (*read)(ushort_t port, void * dst, uint_t length, struct vm_device * dev), + int (*write)(ushort_t port, void * src, uint_t length, struct vm_device * dev)); + +int v3_dev_unhook_io(struct vm_device *dev, + ushort_t port); + + +int v3_attach_device(struct guest_info * vm, struct vm_device * dev); +int v3_detach_device(struct vm_device * dev); + +struct vm_device * v3_allocate_device(char * name, struct v3_device_ops * ops, void * private_data); + + +struct v3_device_info { + char * name; + int (*init)(struct guest_info * info, void * cfg_data); +}; + + +#define device_register(name, init_dev_fn) \ + static char _v3_device_name[] = name; \ + static struct v3_device_info _v3_device \ + __attribute__((__used__)) \ + __attribute__((unused, __section__ ("_v3_devices"), \ + aligned(sizeof(addr_t)))) \ + = {_v3_device_name , init_dev_fn}; + + + + void PrintDebugDevMgr(struct guest_info * info); void PrintDebugDev(struct vm_device * dev); + + + + #endif // ! __V3VEE__ #endif diff --git a/palacios/src/devices/8237_dma.c b/palacios/src/devices/8237_dma.c index 40787a7..5d9a8da 100644 --- a/palacios/src/devices/8237_dma.c +++ b/palacios/src/devices/8237_dma.c @@ -33,9 +33,8 @@ static int dma_init(struct vm_device * dev) { -static struct vm_device_ops dev_ops = { - .init = dma_init, - .deinit = NULL, +static struct v3_device_ops dev_ops = { + .free = NULL, .reset = NULL, .start = NULL, .stop = NULL, diff --git a/palacios/src/devices/8254.c b/palacios/src/devices/8254.c index 1de80e9..7d1acfe 100644 --- a/palacios/src/devices/8254.c +++ b/palacios/src/devices/8254.c @@ -17,8 +17,9 @@ * redistribute, and modify it as specified in the file "V3VEE_LICENSE". */ -#include + #include +#include #include #include #include @@ -613,11 +614,40 @@ static void init_channel(struct channel * ch) { } -static int pit_init(struct vm_device * dev) { - struct pit * state = (struct pit *)dev->private_data; + + +static int pit_free(struct vm_device * dev) { + + return 0; +} + + +static struct v3_device_ops dev_ops = { + .free = pit_free, + .reset = NULL, + .start = NULL, + .stop = NULL, + +}; + + +static int pit_init(struct guest_info * info, void * cfg_data) { + struct pit * pit_state = NULL; + struct vm_device * dev = NULL; + uint_t cpu_khz = V3_CPU_KHZ(); ullong_t reload_val = (ullong_t)cpu_khz * 1000; + pit_state = (struct pit *)V3_Malloc(sizeof(struct pit)); + V3_ASSERT(pit_state != NULL); + + dev = v3_allocate_device("PIT", &dev_ops, pit_state); + + if (v3_attach_device(info, dev) == -1) { + PrintError("Could not attach device %s\n", "PIT"); + return -1; + } + v3_dev_hook_io(dev, CHANNEL0_PORT, &pit_read_channel, &pit_write_channel); v3_dev_hook_io(dev, CHANNEL1_PORT, &pit_read_channel, &pit_write_channel); v3_dev_hook_io(dev, CHANNEL2_PORT, &pit_read_channel, &pit_write_channel); @@ -629,51 +659,28 @@ static int pit_init(struct vm_device * dev) { PrintDebug("\n"); #endif - v3_add_timer(dev->vm, &timer_ops, dev); + v3_add_timer(info, &timer_ops, dev); // Get cpu frequency and calculate the global pit oscilattor counter/cycle do_divll(reload_val, OSC_HZ); - state->pit_counter = reload_val; - state->pit_reload = reload_val; + pit_state->pit_counter = reload_val; + pit_state->pit_reload = reload_val; - init_channel(&(state->ch_0)); - init_channel(&(state->ch_1)); - init_channel(&(state->ch_2)); + init_channel(&(pit_state->ch_0)); + init_channel(&(pit_state->ch_1)); + init_channel(&(pit_state->ch_2)); #ifdef DEBUG_PIT PrintDebug("8254 PIT: CPU MHZ=%d -- pit count=", cpu_khz / 1000); - PrintTraceLL(state->pit_counter); + PrintTraceLL(pit_state->pit_counter); PrintDebug("\n"); #endif return 0; } -static int pit_deinit(struct vm_device * dev) { - return 0; -} - - -static struct vm_device_ops dev_ops = { - .init = pit_init, - .deinit = pit_deinit, - .reset = NULL, - .start = NULL, - .stop = NULL, - -}; - - -struct vm_device * v3_create_pit() { - struct pit * pit_state = NULL; - pit_state = (struct pit *)V3_Malloc(sizeof(struct pit)); - V3_ASSERT(pit_state != NULL); - - struct vm_device * dev = v3_create_device("PIT", &dev_ops, pit_state); - - return dev; -} +device_register("8254_PIT", pit_init); diff --git a/palacios/src/devices/8259a.c b/palacios/src/devices/8259a.c index 83c0ff3..036b0bf 100644 --- a/palacios/src/devices/8259a.c +++ b/palacios/src/devices/8259a.c @@ -18,10 +18,11 @@ */ -#include + #include #include #include +#include #ifndef DEBUG_PIC #undef PrintDebug @@ -685,10 +686,47 @@ static int write_elcr_port(ushort_t port, void * src, uint_t length, struct vm_d -static int pic_init(struct vm_device * dev) { - struct pic_internal * state = (struct pic_internal*)dev->private_data; - v3_register_intr_controller(dev->vm, &intr_ops, state); + + +static int pic_free(struct vm_device * dev) { + v3_dev_unhook_io(dev, MASTER_PORT1); + v3_dev_unhook_io(dev, MASTER_PORT2); + v3_dev_unhook_io(dev, SLAVE_PORT1); + v3_dev_unhook_io(dev, SLAVE_PORT2); + + return 0; +} + + + + + + + +static struct v3_device_ops dev_ops = { + .free = pic_free, + .reset = NULL, + .start = NULL, + .stop = NULL, +}; + + + +static int pic_init(struct guest_info * vm, void * cfg_data) { + struct pic_internal * state = NULL; + state = (struct pic_internal *)V3_Malloc(sizeof(struct pic_internal)); + V3_ASSERT(state != NULL); + + struct vm_device * dev = v3_allocate_device("8259A", &dev_ops, state); + + if (v3_attach_device(vm, dev) == -1) { + PrintError("Could not attach device %s\n", "8259A"); + return -1; + } + + + v3_register_intr_controller(vm, &intr_ops, state); state->master_irr = 0; state->master_isr = 0; @@ -731,36 +769,5 @@ static int pic_init(struct vm_device * dev) { } -static int pic_deinit(struct vm_device * dev) { - v3_dev_unhook_io(dev, MASTER_PORT1); - v3_dev_unhook_io(dev, MASTER_PORT2); - v3_dev_unhook_io(dev, SLAVE_PORT1); - v3_dev_unhook_io(dev, SLAVE_PORT2); - - return 0; -} - - - - - - -static struct vm_device_ops dev_ops = { - .init = pic_init, - .deinit = pic_deinit, - .reset = NULL, - .start = NULL, - .stop = NULL, -}; - - -struct vm_device * v3_create_pic() { - struct pic_internal * state = NULL; - state = (struct pic_internal *)V3_Malloc(sizeof(struct pic_internal)); - V3_ASSERT(state != NULL); - - struct vm_device *device = v3_create_device("8259A", &dev_ops, state); - - return device; -} +device_register("PIC", pic_init); diff --git a/palacios/src/devices/apic.c b/palacios/src/devices/apic.c index 92e6683..13fd991 100644 --- a/palacios/src/devices/apic.c +++ b/palacios/src/devices/apic.c @@ -1020,23 +1020,9 @@ static struct vm_timer_ops timer_ops = { }; -static int apic_init(struct vm_device * dev) { - struct guest_info * info = dev->vm; - struct apic_state * apic = (struct apic_state *)(dev->private_data); - - v3_register_intr_controller(dev->vm, &intr_ops, dev); - v3_add_timer(dev->vm, &timer_ops, dev); - - init_apic_state(apic); - - v3_hook_msr(info, BASE_ADDR_MSR, read_apic_msr, write_apic_msr, dev); - - v3_hook_full_mem(info, apic->base_addr, apic->base_addr + PAGE_SIZE_4KB, apic_read, apic_write, dev); - return 0; -} -static int apic_deinit(struct vm_device * dev) { +static int apic_free(struct vm_device * dev) { struct guest_info * info = dev->vm; v3_unhook_msr(info, BASE_ADDR_MSR); @@ -1045,21 +1031,39 @@ static int apic_deinit(struct vm_device * dev) { } -static struct vm_device_ops dev_ops = { - .init = apic_init, - .deinit = apic_deinit, +static struct v3_device_ops dev_ops = { + .free = apic_free, .reset = NULL, .start = NULL, .stop = NULL, }; -struct vm_device * v3_create_apic() { + +static int apic_init(struct guest_info * vm, void * cfg_data) { PrintDebug("Creating APIC\n"); struct apic_state * apic = (struct apic_state *)V3_Malloc(sizeof(struct apic_state)); - struct vm_device * device = v3_create_device("APIC", &dev_ops, apic); - - return device; + struct vm_device * dev = v3_allocate_device("APIC", &dev_ops, apic); + + if (v3_attach_device(vm, dev) == -1) { + PrintError("Could not attach device %s\n", "APIC"); + return -1; + } + + v3_register_intr_controller(vm, &intr_ops, dev); + v3_add_timer(vm, &timer_ops, dev); + + init_apic_state(apic); + + v3_hook_msr(vm, BASE_ADDR_MSR, read_apic_msr, write_apic_msr, dev); + + v3_hook_full_mem(vm, apic->base_addr, apic->base_addr + PAGE_SIZE_4KB, apic_read, apic_write, dev); + + return 0; } + + + +device_register("LAPIC", &apic_init) diff --git a/palacios/src/devices/bochs_debug.c b/palacios/src/devices/bochs_debug.c index 4d3d284..12f22c9 100644 --- a/palacios/src/devices/bochs_debug.c +++ b/palacios/src/devices/bochs_debug.c @@ -18,8 +18,9 @@ */ -#include + #include +#include #define BUF_SIZE 1024 @@ -109,26 +110,9 @@ static int handle_gen_write(ushort_t port, void * src, uint_t length, struct vm_ } -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); - - - v3_dev_hook_io(dev, BOCHS_PORT1, NULL, &handle_gen_write); - v3_dev_hook_io(dev, BOCHS_PORT2, NULL, &handle_gen_write); - v3_dev_hook_io(dev, BOCHS_INFO_PORT, NULL, &handle_info_write); - v3_dev_hook_io(dev, BOCHS_DEBUG_PORT, NULL, &handle_debug_write); - v3_dev_hook_io(dev, BOCHS_CONSOLE_PORT, NULL, &handle_console_write); - - - return 0; -} -static int debug_deinit(struct vm_device * dev) { +static int debug_free(struct vm_device * dev) { v3_dev_unhook_io(dev, BOCHS_PORT1); v3_dev_unhook_io(dev, BOCHS_PORT2); v3_dev_unhook_io(dev, BOCHS_INFO_PORT); @@ -140,26 +124,46 @@ static int debug_deinit(struct vm_device * dev) { -static struct vm_device_ops dev_ops = { - .init = debug_init, - .deinit = debug_deinit, +static struct v3_device_ops dev_ops = { + .free = debug_free, .reset = NULL, .start = NULL, .stop = NULL, }; -struct vm_device * v3_create_bochs_debug() { - struct debug_state * state = NULL; + + +static int debug_init(struct guest_info * vm, void * cfg_data) { + 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 = v3_create_device("BOCHS Debug", &dev_ops, state); + struct vm_device * dev = v3_allocate_device("BOCHS_DEBUG", &dev_ops, state); + if (v3_attach_device(vm, dev) == -1) { + PrintError("Could not attach device %s\n", "BOCHS_DEBUG"); + return -1; + } + + state->debug_offset = 0; + state->info_offset = 0; + memset(state->debug_buf, 0, BUF_SIZE); + memset(state->info_buf, 0, BUF_SIZE); - return device; + v3_dev_hook_io(dev, BOCHS_PORT1, NULL, &handle_gen_write); + v3_dev_hook_io(dev, BOCHS_PORT2, NULL, &handle_gen_write); + v3_dev_hook_io(dev, BOCHS_INFO_PORT, NULL, &handle_info_write); + v3_dev_hook_io(dev, BOCHS_DEBUG_PORT, NULL, &handle_debug_write); + v3_dev_hook_io(dev, BOCHS_CONSOLE_PORT, NULL, &handle_console_write); + + + return 0; } + + +device_register("BOCHS_DEBUG", debug_init); diff --git a/palacios/src/devices/generic.c b/palacios/src/devices/generic.c index ee1562f..9313055 100644 --- a/palacios/src/devices/generic.c +++ b/palacios/src/devices/generic.c @@ -181,48 +181,8 @@ static int generic_read_port_ignore(ushort_t port, -static int generic_init_device(struct vm_device * dev) { - struct generic_internal * state = (struct generic_internal *)(dev->private_data); - - PrintDebug("generic: init_device\n"); - generic_reset_device(dev); - - - if (PORT_HOOKS) { // This is a runtime conditional on a #define - struct port_range * tmp = NULL; - - list_for_each_entry(tmp, &(state->port_list), range_link) { - uint_t i = 0; - - PrintDebug("generic: hooking ports 0x%x to 0x%x as %s\n", - tmp->start, tmp->end, - (tmp->type == GENERIC_PRINT_AND_PASSTHROUGH) ? "print-and-passthrough" : "print-and-ignore"); - - for (i = tmp->start; i <= tmp->end; i++) { - if (tmp->type == GENERIC_PRINT_AND_PASSTHROUGH) { - - if (v3_dev_hook_io(dev, i, &generic_read_port_passthrough, &generic_write_port_passthrough)) { - PrintDebug("generic: can't hook port 0x%x (already hooked?)\n", i); - } - - } else if (tmp->type == GENERIC_PRINT_AND_IGNORE) { - - if (v3_dev_hook_io(dev, i, &generic_read_port_ignore, &generic_write_port_ignore)) { - PrintDebug("generic: can't hook port 0x%x (already hooked?)\n", i); - } - } - } - } - } else { - PrintDebug("generic: hooking ports not supported\n"); - } - - - return 0; -} - -static int generic_deinit_device(struct vm_device * dev) { +static int generic_free(struct vm_device * dev) { struct generic_internal * state = (struct generic_internal *)(dev->private_data); @@ -262,9 +222,8 @@ static int generic_deinit_device(struct vm_device * dev) { -static struct vm_device_ops dev_ops = { - .init = generic_init_device, - .deinit = generic_deinit_device, +static struct v3_device_ops dev_ops = { + .free = generic_free, .reset = generic_reset_device, .start = generic_start_device, .stop = generic_stop_device, @@ -298,14 +257,60 @@ int v3_generic_add_port_range(struct vm_device * dev, uint_t start, uint_t end, return 0; } -struct vm_device * v3_create_generic() { - struct generic_internal * generic_state = (struct generic_internal *)V3_Malloc(sizeof(struct generic_internal)); + + + +static int generic_init(struct guest_info * vm, void * cfg_data) { + struct generic_internal * state = (struct generic_internal *)V3_Malloc(sizeof(struct generic_internal)); - generic_state->num_port_ranges = 0; + state->num_port_ranges = 0; - INIT_LIST_HEAD(&(generic_state->port_list)); + INIT_LIST_HEAD(&(state->port_list)); - struct vm_device * device = v3_create_device("GENERIC", &dev_ops, generic_state); + struct vm_device * dev = v3_allocate_device("GENERIC", &dev_ops, state); - return device; + + if (v3_attach_device(vm, dev) == -1) { + PrintError("Could not attach device %s\n", "GENERIC"); + return -1; + } + + PrintDebug("generic: init_device\n"); + generic_reset_device(dev); + + + if (PORT_HOOKS) { // This is a runtime conditional on a #define + struct port_range * tmp = NULL; + + list_for_each_entry(tmp, &(state->port_list), range_link) { + uint_t i = 0; + + PrintDebug("generic: hooking ports 0x%x to 0x%x as %s\n", + tmp->start, tmp->end, + (tmp->type == GENERIC_PRINT_AND_PASSTHROUGH) ? "print-and-passthrough" : "print-and-ignore"); + + for (i = tmp->start; i <= tmp->end; i++) { + if (tmp->type == GENERIC_PRINT_AND_PASSTHROUGH) { + + if (v3_dev_hook_io(dev, i, &generic_read_port_passthrough, &generic_write_port_passthrough)) { + PrintDebug("generic: can't hook port 0x%x (already hooked?)\n", i); + } + + } else if (tmp->type == GENERIC_PRINT_AND_IGNORE) { + + if (v3_dev_hook_io(dev, i, &generic_read_port_ignore, &generic_write_port_ignore)) { + PrintDebug("generic: can't hook port 0x%x (already hooked?)\n", i); + } + } + } + + } + } else { + PrintDebug("generic: hooking ports not supported\n"); + } + + + return 0; } + +device_register("GENERIC", generic_init) diff --git a/palacios/src/devices/i440fx.c b/palacios/src/devices/i440fx.c index d631235..8621d33 100644 --- a/palacios/src/devices/i440fx.c +++ b/palacios/src/devices/i440fx.c @@ -18,7 +18,7 @@ */ #include -#include +#include #include struct i440_state { @@ -38,11 +38,45 @@ static int io_write(ushort_t port, void * src, uint_t length, struct vm_device * -static int i440_init(struct vm_device * dev) { - struct i440_state * state = (struct i440_state *)(dev->private_data); + + +static int i440_free(struct vm_device * dev) { + return 0; +} + +static struct v3_device_ops dev_ops = { + .free = i440_free, + .reset = NULL, + .start = NULL, + .stop = NULL, +}; + + + + +static int i440_init(struct guest_info * vm, void * cfg_data) { struct pci_device * pci_dev = NULL; struct v3_pci_bar bars[6]; int i; + struct i440_state * state = NULL; + struct vm_device * pci = v3_find_dev(vm, (char *)cfg_data); + + if (!pci) { + PrintError("could not find PCI Device\n"); + return -1; + } + + state = (struct i440_state *)V3_Malloc(sizeof(struct i440_state)); + + state->pci = pci; + + struct vm_device * dev = v3_allocate_device("i440FX", &dev_ops, state); + + if (v3_attach_device(vm, dev) == -1) { + PrintError("Could not attach device %s\n", "i440FX"); + return -1; + } + for (i = 0; i < 4; i++) { v3_dev_hook_io(dev, 0x0cf8 + i, @@ -73,29 +107,4 @@ static int i440_init(struct vm_device * dev) { return 0; } - -static int i440_deinit(struct vm_device * dev) { - return 0; -} - -static struct vm_device_ops dev_ops = { - .init = i440_init, - .deinit = i440_deinit, - .reset = NULL, - .start = NULL, - .stop = NULL, -}; - - - -struct vm_device * v3_create_i440fx(struct vm_device * pci) { - struct i440_state * state = NULL; - - state = (struct i440_state *)V3_Malloc(sizeof(struct i440_state)); - - state->pci = pci; - - struct vm_device * i440_dev = v3_create_device("i440FX", &dev_ops, state); - - return i440_dev; -} +device_register("i440FX", i440_init) diff --git a/palacios/src/devices/ide.c b/palacios/src/devices/ide.c index 17d9461..23b2291 100644 --- a/palacios/src/devices/ide.c +++ b/palacios/src/devices/ide.c @@ -1434,10 +1434,64 @@ static int init_ide_state(struct vm_device * dev) { -static int init_ide(struct vm_device * dev) { - struct ide_internal * ide = (struct ide_internal *)(dev->private_data); +static int ide_free(struct vm_device * dev) { + // unhook io ports.... + // deregister from PCI? + return 0; +} + + +static struct v3_device_ops dev_ops = { + .free = ide_free, + .reset = NULL, + .start = NULL, + .stop = NULL, +}; + + + +static int ide_init(struct guest_info * vm, void * cfg_data) { + struct ide_internal * ide = (struct ide_internal *)V3_Malloc(sizeof(struct ide_internal)); + struct ide_cfg * cfg = (struct ide_cfg *)(cfg_data); + PrintDebug("IDE: Initializing IDE\n"); + memset(ide, 0, sizeof(struct ide_internal)); + + + if (cfg->pci != NULL) { + if (cfg->southbridge == NULL) { + PrintError("PCI Enabled BUT southbridge is NULL\n"); + return -1; + } + + ide->pci_bus = v3_find_dev(vm, (char *)cfg->pci); + + if (ide->pci_bus == NULL) { + PrintError("Could not find PCI device\n"); + return -1; + } + + struct vm_device * southbridge = v3_find_dev(vm, cfg->southbridge); + + if (!southbridge) { + PrintError("Could not find southbridge\n"); + return -1; + } + + ide->southbridge = (struct v3_southbridge *)(southbridge->private_data); + } + + + PrintDebug("IDE: Creating IDE bus x 2\n"); + + struct vm_device * dev = v3_allocate_device("IDE", &dev_ops, ide); + + if (v3_attach_device(vm, dev) == -1) { + PrintError("Could not attach device %s\n", "IDE"); + return -1; + } + if (init_ide_state(dev) == -1) { PrintError("Failed to initialize IDE state\n"); @@ -1554,42 +1608,13 @@ static int init_ide(struct vm_device * dev) { } -static int deinit_ide(struct vm_device * dev) { - // unhook io ports.... - // deregister from PCI? - return 0; -} +device_register("IDE", ide_init) -static struct vm_device_ops dev_ops = { - .init = init_ide, - .deinit = deinit_ide, - .reset = NULL, - .start = NULL, - .stop = NULL, -}; - - -struct vm_device * v3_create_ide(struct vm_device * pci_bus, struct vm_device * southbridge_dev) { - struct ide_internal * ide = (struct ide_internal *)V3_Malloc(sizeof(struct ide_internal)); - - memset(ide, 0, sizeof(struct ide_internal)); - if (pci_bus != NULL) { - if (southbridge_dev == NULL) { - PrintError("PCI Enabled BUT southbridge is NULL\n"); - return NULL; - } - ide->pci_bus = pci_bus; - ide->southbridge = (struct v3_southbridge *)(southbridge_dev->private_data); - } - PrintDebug("IDE: Creating IDE bus x 2\n"); - - return v3_create_device("IDE", &dev_ops, ide); -} diff --git a/palacios/src/devices/io_apic.c b/palacios/src/devices/io_apic.c index 1e032b6..8f4e085 100644 --- a/palacios/src/devices/io_apic.c +++ b/palacios/src/devices/io_apic.c @@ -17,9 +17,9 @@ * redistribute, and modify it as specified in the file "V3VEE_LICENSE". */ -#include -#include +#include +#include #include @@ -301,30 +301,17 @@ static struct intr_ctrl_ops intr_ops = { }; -static int io_apic_init(struct vm_device * dev) { - struct guest_info * info = dev->vm; - struct io_apic_state * ioapic = (struct io_apic_state *)(dev->private_data); - - v3_register_intr_controller(dev->vm, &intr_ops, dev); - init_ioapic_state(ioapic); - - v3_hook_full_mem(info, ioapic->base_addr, ioapic->base_addr + PAGE_SIZE_4KB, - ioapic_read, ioapic_write, dev); - - return 0; -} -static int io_apic_deinit(struct vm_device * dev) { +static int io_apic_free(struct vm_device * dev) { // struct guest_info * info = dev->vm; return 0; } -static struct vm_device_ops dev_ops = { - .init = io_apic_init, - .deinit = io_apic_deinit, +static struct v3_device_ops dev_ops = { + .free = io_apic_free, .reset = NULL, .start = NULL, .stop = NULL, @@ -332,13 +319,37 @@ static struct vm_device_ops dev_ops = { -struct vm_device * v3_create_io_apic(struct vm_device * apic) { +static int ioapic_init(struct guest_info * vm, void * cfg_data) { + struct vm_device * apic = v3_find_dev(vm, (char *)cfg_data); + + if (!apic) { + PrintError("Could not locate APIC device\n"); + return -1; + } + PrintDebug("Creating IO APIC\n"); struct io_apic_state * ioapic = (struct io_apic_state *)V3_Malloc(sizeof(struct io_apic_state)); + ioapic->apic = apic; - struct vm_device * device = v3_create_device("IOAPIC", &dev_ops, ioapic); + struct vm_device * dev = v3_allocate_device("IOAPIC", &dev_ops, ioapic); + - return device; + if (v3_attach_device(vm, dev) == -1) { + PrintError("Could not attach device %s\n", "IOAPIC"); + return -1; + } + + + v3_register_intr_controller(vm, &intr_ops, dev); + init_ioapic_state(ioapic); + + v3_hook_full_mem(vm, ioapic->base_addr, ioapic->base_addr + PAGE_SIZE_4KB, + ioapic_read, ioapic_write, dev); + + return 0; } + + +device_register("IOAPIC", ioapic_init) diff --git a/palacios/src/devices/keyboard.c b/palacios/src/devices/keyboard.c index 8e378f2..0fcdc90 100644 --- a/palacios/src/devices/keyboard.c +++ b/palacios/src/devices/keyboard.c @@ -17,8 +17,8 @@ * redistribute, and modify it as specified in the file "V3VEE_LICENSE". */ -#include #include +#include #include #include @@ -934,39 +934,8 @@ static int keyboard_read_input(ushort_t port, void * dest, uint_t length, struct -static int keyboard_init_device(struct vm_device * dev) { - struct keyboard_internal * state = (struct keyboard_internal *)(dev->private_data); - - PrintDebug("keyboard: init_device\n"); - - keyboard_reset_device(dev); - - v3_lock_init(&(state->kb_lock)); - - - // hook ports - v3_dev_hook_io(dev, KEYBOARD_64H, &keyboard_read_status, &keyboard_write_command); - v3_dev_hook_io(dev, KEYBOARD_60H, &keyboard_read_input, &keyboard_write_output); - - v3_hook_host_event(dev->vm, HOST_KEYBOARD_EVT, V3_HOST_EVENT_HANDLER(key_event_handler), dev); - v3_hook_host_event(dev->vm, HOST_MOUSE_EVT, V3_HOST_EVENT_HANDLER(mouse_event_handler), dev); - - -#if KEYBOARD_DEBUG_80H - v3_dev_hook_io(dev, KEYBOARD_DELAY_80H, &keyboard_read_delay, &keyboard_write_delay); -#endif - - - // - // We do not hook the IRQ here. Instead, the underlying device driver - // is responsible to call us back - // - - return 0; -} - -static int keyboard_deinit_device(struct vm_device * dev) { +static int keyboard_free(struct vm_device * dev) { v3_dev_unhook_io(dev, KEYBOARD_60H); v3_dev_unhook_io(dev, KEYBOARD_64H); @@ -981,9 +950,8 @@ static int keyboard_deinit_device(struct vm_device * dev) { -static struct vm_device_ops dev_ops = { - .init = keyboard_init_device, - .deinit = keyboard_deinit_device, +static struct v3_device_ops dev_ops = { + .free = keyboard_free, .reset = keyboard_reset_device, .start = keyboard_start_device, .stop = keyboard_stop_device, @@ -992,9 +960,12 @@ static struct vm_device_ops dev_ops = { -struct vm_device * v3_create_keyboard() { +static int keyboard_init(struct guest_info * vm, void * cfg_data) { struct keyboard_internal * keyboard_state = NULL; + + PrintDebug("keyboard: init_device\n"); + keyboard_state = (struct keyboard_internal *)V3_Malloc(sizeof(struct keyboard_internal)); keyboard_state->mouse_queue.start = 0; @@ -1007,7 +978,40 @@ struct vm_device * v3_create_keyboard() { keyboard_state->mouse_enabled = 0; - struct vm_device * device = v3_create_device("KEYBOARD", &dev_ops, keyboard_state); + struct vm_device * dev = v3_allocate_device("KEYBOARD", &dev_ops, keyboard_state); + + if (v3_attach_device(vm, dev) == -1) { + PrintError("Could not attach device %s\n", "KEYBOARD"); + return -1; + } + + + keyboard_reset_device(dev); + + + v3_lock_init(&(keyboard_state->kb_lock)); + + + // hook ports + v3_dev_hook_io(dev, KEYBOARD_64H, &keyboard_read_status, &keyboard_write_command); + v3_dev_hook_io(dev, KEYBOARD_60H, &keyboard_read_input, &keyboard_write_output); + + v3_hook_host_event(vm, HOST_KEYBOARD_EVT, V3_HOST_EVENT_HANDLER(key_event_handler), dev); + v3_hook_host_event(vm, HOST_MOUSE_EVT, V3_HOST_EVENT_HANDLER(mouse_event_handler), dev); - return device; + +#if KEYBOARD_DEBUG_80H + v3_dev_hook_io(dev, KEYBOARD_DELAY_80H, &keyboard_read_delay, &keyboard_write_delay); +#endif + + + // + // We do not hook the IRQ here. Instead, the underlying device driver + // is responsible to call us back + // + + return 0; } + + +device_register("KEYBOARD", keyboard_init) diff --git a/palacios/src/devices/lnx_virtio_blk.c b/palacios/src/devices/lnx_virtio_blk.c index 4e0c14c..f44d616 100644 --- a/palacios/src/devices/lnx_virtio_blk.c +++ b/palacios/src/devices/lnx_virtio_blk.c @@ -51,11 +51,49 @@ static int virtio_pci_read(uint16_t port, void * dst, uint_t length, struct vm_d return -1; } -static int virtio_init(struct vm_device * dev) { - struct blk_state * virtio = (struct blk_state *)(dev->private_data); + + +static int virtio_free(struct vm_device * dev) { + return -1; +} + + + +static struct v3_device_ops dev_ops = { + .free = virtio_free, + .reset = NULL, + .start = NULL, + .stop = NULL, +}; + + + + + +static int virtio_init(struct guest_info * vm, void * cfg_data) { + struct blk_state * virtio = NULL; + struct vm_device * pci_bus = (struct vm_device *)cfg_data; + PrintDebug("Initializing VIRTIO Block device\n"); + if (pci_bus == NULL) { + PrintError("VirtIO requires a PCI bus\n"); + return -1; + } + + virtio = (struct blk_state *)V3_Malloc(sizeof(struct blk_state)); + + virtio->pci_bus = pci_bus; + + struct vm_device * dev = v3_allocate_device("VIRTIO_BLK", &dev_ops, virtio); + if (v3_attach_device(vm, dev) == -1) { + PrintError("Could not attach device %s\n", "LNX_VIRTIO_BLK"); + return -1; + } + + + if (virtio->pci_bus != NULL) { struct v3_pci_bar bars[6]; struct pci_device * pci_dev = NULL; @@ -115,36 +153,5 @@ static int virtio_init(struct vm_device * dev) { return -1; } -static int virtio_deinit(struct vm_device * dev) { - return -1; -} - - - -static struct vm_device_ops dev_ops = { - .init = virtio_init, - .deinit = virtio_deinit, - .reset = NULL, - .start = NULL, - .stop = NULL, -}; - - -struct vm_device * v3_create_virtio(struct vm_device * pci_bus) { - struct blk_state * virtio = NULL; - - PrintDebug("Creating VirtIO Block device\n"); - - if (pci_bus == NULL) { - PrintError("VirtIO requires a PCI bus\n"); - return NULL; - } - - - virtio = (struct blk_state *)V3_Malloc(sizeof(struct blk_state)); - - virtio->pci_bus = pci_bus; - - return v3_create_device("VIRTIO_BLK", &dev_ops, virtio); -} +device_register("LNX_VIRTIO_BLK", virtio_init) diff --git a/palacios/src/devices/ne2k.c b/palacios/src/devices/ne2k.c index 0a14e1e..e535a1c 100644 --- a/palacios/src/devices/ne2k.c +++ b/palacios/src/devices/ne2k.c @@ -1169,7 +1169,7 @@ static int ne2k_deinit_device(struct vm_device *dev) { } -static struct vm_device_ops dev_ops = { +static struct v3_device_ops dev_ops = { .init = ne2k_init_device, .deinit = ne2k_deinit_device, .reset = ne2k_reset_device, diff --git a/palacios/src/devices/net_cd.c b/palacios/src/devices/net_cd.c index 4446e12..26517bb 100644 --- a/palacios/src/devices/net_cd.c +++ b/palacios/src/devices/net_cd.c @@ -164,8 +164,22 @@ static struct v3_ide_cd_ops cd_ops = { }; -static int cd_init(struct vm_device * dev) { - struct cd_state * cd = (struct cd_state *)(dev->private_data); + + +static int cd_free(struct vm_device * dev) { + return 0; +} + +static struct v3_device_ops dev_ops = { + .free = cd_free, + .reset = NULL, + .start = NULL, + .stop = NULL, +}; + + + +static int socket_init(struct cd_state * cd) { char header[64]; PrintDebug("Intializing Net CD\n"); @@ -210,6 +224,41 @@ static int cd_init(struct vm_device * dev) { PrintDebug("Capacity: %p\n", (void *)(cd->capacity)); } + return 0; +} + +static int cd_init(struct guest_info * vm, void * cfg_data) { + struct net_cd_cfg * cfg = (struct net_cd_cfg *)cfg_data; + struct cd_state * cd = (struct cd_state *)V3_Malloc(sizeof(struct cd_state)); + + PrintDebug("Registering Net CD at %s:%d disk=%s\n", cfg->ip_str, cfg->port, cfg->disk_tag); + + strncpy(cd->disk_name, cfg->disk_tag, sizeof(cd->disk_name)); + cd->ip_addr = v3_inet_addr(cfg->ip_str); + cd->port = cfg->port; + + cd->ide = (struct vm_device * )v3_find_dev(vm, cfg->ide); + + if (cd->ide == 0) { + PrintError("Could not find backend %s\n", cfg->ide); + return -1; + } + + cd->bus = cfg->bus; + cd->drive = cfg->drive; + + struct vm_device * dev = v3_allocate_device("NET-CD", &dev_ops, cd); + + + if (v3_attach_device(vm, dev) == -1) { + PrintError("Could not attach device %s\n", "NET-CD"); + return -1; + } + + if (socket_init(cd) == -1) { + PrintError("Could not initialize socket connection\n"); + return -1; + } PrintDebug("Registering CD\n"); @@ -218,40 +267,11 @@ static int cd_init(struct vm_device * dev) { } PrintDebug("intialization done\n"); - - return 0; -} - -static int cd_deinit(struct vm_device * dev) { return 0; } -static struct vm_device_ops dev_ops = { - .init = cd_init, - .deinit = cd_deinit, - .reset = NULL, - .start = NULL, - .stop = NULL, -}; -struct vm_device * v3_create_net_cd(struct vm_device * ide, - uint_t bus, uint_t drive, - const char * ip_str, uint16_t port, - const char * disk_tag) { - struct cd_state * cd = (struct cd_state *)V3_Malloc(sizeof(struct cd_state)); - - PrintDebug("Registering Net CD at %s:%d disk=%s\n", ip_str, port, disk_tag); - strncpy(cd->disk_name, disk_tag, sizeof(cd->disk_name)); - cd->ip_addr = v3_inet_addr(ip_str); - cd->port = port; - cd->ide = ide; - cd->bus = bus; - cd->drive = drive; - - struct vm_device * cd_dev = v3_create_device("NET-CD", &dev_ops, cd); - - return cd_dev; -} +device_register("NET-CD", cd_init) diff --git a/palacios/src/devices/net_hd.c b/palacios/src/devices/net_hd.c index 26f1d6c..bed3e42 100644 --- a/palacios/src/devices/net_hd.c +++ b/palacios/src/devices/net_hd.c @@ -213,8 +213,22 @@ static struct v3_ide_hd_ops hd_ops = { }; -static int hd_init(struct vm_device * dev) { - struct hd_state * hd = (struct hd_state *)(dev->private_data); + + + +static int hd_free(struct vm_device * dev) { + return 0; +} + +static struct v3_device_ops dev_ops = { + .free = hd_free, + .reset = NULL, + .start = NULL, + .stop = NULL, +}; + + +static int socket_init(struct hd_state * hd) { char header[64]; PrintDebug("Intializing Net HD\n"); @@ -258,47 +272,55 @@ static int hd_init(struct vm_device * dev) { PrintDebug("Capacity: %p\n", (void *)(hd->capacity)); } - PrintDebug("Registering HD\n"); - if (v3_ide_register_harddisk(hd->ide, hd->bus, hd->drive, "V3-NET-HD", &hd_ops, dev) == -1) { - return -1; - } - - PrintDebug("intialization done\n"); return 0; } -static int hd_deinit(struct vm_device * dev) { - return 0; -} +static int hd_init(struct guest_info * vm, void * cfg_data) { + struct hd_state * hd = (struct hd_state *)V3_Malloc(sizeof(struct hd_state)); + struct net_hd_cfg * cfg = (struct net_hd_cfg *)cfg_data; -static struct vm_device_ops dev_ops = { - .init = hd_init, - .deinit = hd_deinit, - .reset = NULL, - .start = NULL, - .stop = NULL, -}; + PrintDebug("Registering Net HD at %s:%d disk=%s\n", cfg->ip_str, cfg->port, cfg->disk_tag); -struct vm_device * v3_create_net_hd(struct vm_device * ide, - uint_t bus, uint_t drive, - const char * ip_str, uint16_t port, - const char * disk_tag) { - struct hd_state * hd = (struct hd_state *)V3_Malloc(sizeof(struct hd_state)); + strncpy(hd->disk_name, cfg->disk_tag, sizeof(hd->disk_name)); + hd->ip_addr = v3_inet_addr(cfg->ip_str); + hd->port = cfg->port; - PrintDebug("Registering Net HD at %s:%d disk=%s\n", ip_str, port, disk_tag); + hd->ide = v3_find_dev(vm, cfg->ide); - strncpy(hd->disk_name, disk_tag, sizeof(hd->disk_name)); - hd->ip_addr = v3_inet_addr(ip_str); - hd->port = port; + if (hd->ide == 0) { + PrintError("Could not find backend %s\n", cfg->ide); + return -1; + } - hd->ide = ide; - hd->bus = bus; - hd->drive = drive; + hd->bus = cfg->bus; + hd->drive = cfg->drive; - struct vm_device * hd_dev = v3_create_device("NET-HD", &dev_ops, hd); + struct vm_device * dev = v3_allocate_device("NET-HD", &dev_ops, hd); + + if (v3_attach_device(vm, dev) == -1) { + PrintError("Could not attach device %s\n", "NET-HD"); + return -1; + } + + if (socket_init(hd) == -1) { + PrintError("could not initialize network connection\n"); + return -1; + } + - return hd_dev; + PrintDebug("Registering HD\n"); + + if (v3_ide_register_harddisk(hd->ide, hd->bus, hd->drive, "V3-NET-HD", &hd_ops, dev) == -1) { + return -1; + } + + PrintDebug("intialization done\n"); + + return 0; } + + +device_register("NET-HD", hd_init) diff --git a/palacios/src/devices/nvram.c b/palacios/src/devices/nvram.c index f43cbd0..5c70d3b 100644 --- a/palacios/src/devices/nvram.c +++ b/palacios/src/devices/nvram.c @@ -18,7 +18,7 @@ */ -#include +#include #include #include @@ -768,25 +768,11 @@ static int nvram_write_data_port(ushort_t port, -static int nvram_init_device(struct vm_device * dev) { - PrintDebug("nvram: init_device\n"); - - init_nvram_state(dev); - - // hook ports - v3_dev_hook_io(dev, NVRAM_REG_PORT, NULL, &nvram_write_reg_port); - v3_dev_hook_io(dev, NVRAM_DATA_PORT, &nvram_read_data_port, &nvram_write_data_port); - - v3_hook_host_event(dev->vm, HOST_TIMER_EVT, V3_HOST_EVENT_HANDLER(handle_timer_event), dev); - return 0; -} - -static int nvram_deinit_device(struct vm_device * dev) { +static int nvram_free(struct vm_device * dev) { v3_dev_unhook_io(dev, NVRAM_REG_PORT); v3_dev_unhook_io(dev, NVRAM_DATA_PORT); - nvram_reset_device(dev); return 0; } @@ -794,9 +780,8 @@ static int nvram_deinit_device(struct vm_device * dev) { -static struct vm_device_ops dev_ops = { - .init = nvram_init_device, - .deinit = nvram_deinit_device, +static struct v3_device_ops dev_ops = { + .free = nvram_free, .reset = nvram_reset_device, .start = nvram_start_device, .stop = nvram_stop_device, @@ -805,16 +790,40 @@ static struct vm_device_ops dev_ops = { -struct vm_device * v3_create_nvram(struct vm_device * ide) { + +static int nvram_init(struct guest_info * vm, void * cfg_data) { struct nvram_internal * nvram_state = NULL; + struct vm_device * ide = v3_find_dev(vm, (char *)cfg_data); + + if (!ide) { + PrintError("Could not find IDE device\n"); + return -1; + } + PrintDebug("nvram: init_device\n"); nvram_state = (struct nvram_internal *)V3_Malloc(sizeof(struct nvram_internal) + 1000); PrintDebug("nvram: internal at %p\n", (void *)nvram_state); nvram_state->ide = ide; - struct vm_device * device = v3_create_device("NVRAM", &dev_ops, nvram_state); + struct vm_device * dev = v3_allocate_device("NVRAM", &dev_ops, nvram_state); + + + if (v3_attach_device(vm, dev) == -1) { + PrintError("Could not attach device %s\n", "NVRAM"); + return -1; + } + + init_nvram_state(dev); + + // hook ports + v3_dev_hook_io(dev, NVRAM_REG_PORT, NULL, &nvram_write_reg_port); + v3_dev_hook_io(dev, NVRAM_DATA_PORT, &nvram_read_data_port, &nvram_write_data_port); + + v3_hook_host_event(vm, HOST_TIMER_EVT, V3_HOST_EVENT_HANDLER(handle_timer_event), dev); - return device; + return 0; } + +device_register("NVRAM", nvram_init) diff --git a/palacios/src/devices/os_debug.c b/palacios/src/devices/os_debug.c index de30961..e6ecf32 100644 --- a/palacios/src/devices/os_debug.c +++ b/palacios/src/devices/os_debug.c @@ -18,8 +18,9 @@ */ -#include + #include +#include #include #define BUF_SIZE 1024 @@ -73,19 +74,8 @@ static int handle_hcall(struct guest_info * info, uint_t hcall_id, void * priv_d } -static int debug_init(struct vm_device * dev) { - struct debug_state * state = (struct debug_state *)dev->private_data; - - v3_dev_hook_io(dev, DEBUG_PORT1, NULL, &handle_gen_write); - v3_register_hypercall(dev->vm, DEBUG_HCALL, handle_hcall, dev); - - state->debug_offset = 0; - memset(state->debug_buf, 0, BUF_SIZE); - - return 0; -} -static int debug_deinit(struct vm_device * dev) { +static int debug_free(struct vm_device * dev) { v3_dev_unhook_io(dev, DEBUG_PORT1); @@ -95,24 +85,39 @@ static int debug_deinit(struct vm_device * dev) { -static struct vm_device_ops dev_ops = { - .init = debug_init, - .deinit = debug_deinit, +static struct v3_device_ops dev_ops = { + .free = debug_free, .reset = NULL, .start = NULL, .stop = NULL, }; -struct vm_device * v3_create_os_debug() { + + +static int debug_init(struct guest_info * vm, void * cfg_data) { struct debug_state * state = NULL; state = (struct debug_state *)V3_Malloc(sizeof(struct debug_state)); PrintDebug("Creating OS Debug Device\n"); - struct vm_device * device = v3_create_device("OS Debug", &dev_ops, state); + struct vm_device * dev = v3_allocate_device("OS_DEBUG", &dev_ops, state); - return device; + if (v3_attach_device(vm, dev) == -1) { + PrintError("Could not attach device %s\n", "OS_DEBUG"); + return -1; + } + + v3_dev_hook_io(dev, DEBUG_PORT1, NULL, &handle_gen_write); + v3_register_hypercall(vm, DEBUG_HCALL, handle_hcall, dev); + + state->debug_offset = 0; + memset(state->debug_buf, 0, BUF_SIZE); + + return 0; } + + +device_register("OS_DEBUG", debug_init) diff --git a/palacios/src/devices/para_net.c b/palacios/src/devices/para_net.c index 405b9c6..13c5524 100644 --- a/palacios/src/devices/para_net.c +++ b/palacios/src/devices/para_net.c @@ -17,8 +17,9 @@ * redistribute, and modify it as specified in the file "V3VEE_LICENSE". */ -#include + #include +#include #include #include @@ -82,46 +83,51 @@ static int macaddr_call(struct guest_info * info, uint_t call_no, void * priv_da return 0; } -static int net_init(struct vm_device * dev) { - struct nic_state * nic = (struct nic_state *)dev->private_data; - - v3_register_hypercall(dev->vm, TX_HYPERCALL, tx_call, nic); - v3_register_hypercall(dev->vm, RX_HYPERCALL, rx_call, nic); - v3_register_hypercall(dev->vm, MACADDR_HYPERCALL, macaddr_call, nic); - - nic->mac_addr[0] = 0x52; - nic->mac_addr[1] = 0x54; - nic->mac_addr[2] = 0x00; - nic->mac_addr[3] = 0x12; - nic->mac_addr[4] = 0x34; - nic->mac_addr[5] = 0x56; - - return 0; -} -static int net_deinit(struct vm_device * dev) { +static int net_free(struct vm_device * dev) { return 0; } -static struct vm_device_ops dev_ops = { - .init = net_init, - .deinit = net_deinit, +static struct v3_device_ops dev_ops = { + .free = net_free, .reset = NULL, .start = NULL, .stop = NULL, }; -struct vm_device * v3_create_para_net() { + + +static int net_init(struct guest_info * vm, void * cfg_data) { struct nic_state * state = NULL; state = (struct nic_state *)V3_Malloc(sizeof(struct nic_state)); PrintDebug("Creating VMNet Device\n"); - struct vm_device * device = v3_create_device("VMNET", &dev_ops, state); + struct vm_device * dev = v3_allocate_device("VMNET", &dev_ops, state); - return device; + if (v3_attach_device(vm, dev) == -1) { + PrintError("Could not attach device %s\n", "VMNET"); + return -1; + } + + + v3_register_hypercall(vm, TX_HYPERCALL, tx_call, state); + v3_register_hypercall(vm, RX_HYPERCALL, rx_call, state); + v3_register_hypercall(vm, MACADDR_HYPERCALL, macaddr_call, state); + + state->mac_addr[0] = 0x52; + state->mac_addr[1] = 0x54; + state->mac_addr[2] = 0x00; + state->mac_addr[3] = 0x12; + state->mac_addr[4] = 0x34; + state->mac_addr[5] = 0x56; + + return 0; } + + +device_register("VMNET", net_init) diff --git a/palacios/src/devices/pci.c b/palacios/src/devices/pci.c index 7832a08..970d738 100644 --- a/palacios/src/devices/pci.c +++ b/palacios/src/devices/pci.c @@ -556,7 +556,7 @@ static int pci_stop_device(struct vm_device * dev) { -static int pci_deinit_device(struct vm_device * dev) { +static int pci_free(struct vm_device * dev) { int i = 0; for (i = 0; i < 4; i++){ @@ -581,14 +581,30 @@ static void init_pci_busses(struct pci_internal * pci_state) { -static int pci_init_device(struct vm_device * dev) { - struct pci_internal * pci_state = (struct pci_internal *)dev->private_data; + +static struct v3_device_ops dev_ops = { + .free = pci_free, + .reset = pci_reset_device, + .start = pci_start_device, + .stop = pci_stop_device, +}; + + + + +static int pci_init(struct guest_info * vm, void * cfg_data) { + struct pci_internal * pci_state = V3_Malloc(sizeof(struct pci_internal)); int i = 0; - PrintDebug("pci: init_device\n"); + PrintDebug("PCI internal at %p\n",(void *)pci_state); + + struct vm_device * dev = v3_allocate_device("PCI", &dev_ops, pci_state); + + if (v3_attach_device(vm, dev) == -1) { + PrintError("Could not attach device %s\n", "PCI"); + return -1; + } - // JRL: Fix this.... - // dev->vm->pci = dev; //should be in vmm_config.c pci_state->addr_reg.val = 0; @@ -605,25 +621,7 @@ static int pci_init_device(struct vm_device * dev) { } -static struct vm_device_ops dev_ops = { - .init = pci_init_device, - .deinit = pci_deinit_device, - .reset = pci_reset_device, - .start = pci_start_device, - .stop = pci_stop_device, -}; - - -struct vm_device * v3_create_pci() { - struct pci_internal * pci_state = V3_Malloc(sizeof(struct pci_internal)); - - PrintDebug("PCI internal at %p\n",(void *)pci_state); - - struct vm_device * device = v3_create_device("PCI", &dev_ops, pci_state); - - return device; -} - +device_register("PCI", pci_init) static inline int init_bars(struct pci_device * pci_dev) { diff --git a/palacios/src/devices/piix3.c b/palacios/src/devices/piix3.c index d20ad3c..2eae985 100644 --- a/palacios/src/devices/piix3.c +++ b/palacios/src/devices/piix3.c @@ -21,7 +21,7 @@ * redistribute, and modify it as specified in the file "V3VEE_LICENSE". */ -#include + #include #include #include @@ -64,7 +64,25 @@ static int reset_piix3(struct vm_device * dev) { } -static int init_piix3(struct vm_device * dev) { + + + +static int piix_free(struct vm_device * dev) { + return 0; +} + + +static struct v3_device_ops dev_ops = { + .free = piix_free, + .reset = reset_piix3, + .start = NULL, + .stop = NULL, +}; + + + + +static int setup_pci(struct vm_device * dev) { struct v3_southbridge * piix3 = (struct v3_southbridge *)(dev->private_data); struct pci_device * pci_dev = NULL; struct v3_pci_bar bars[6]; @@ -95,31 +113,30 @@ static int init_piix3(struct vm_device * dev) { return 0; } - -static int deinit_piix3(struct vm_device * dev) { - return 0; -} - - -static struct vm_device_ops dev_ops = { - .init = init_piix3, - .deinit = deinit_piix3, - .reset = reset_piix3, - .start = NULL, - .stop = NULL, -}; - - -struct vm_device * v3_create_piix3(struct vm_device * pci) { +static int piix3_init(struct guest_info * vm, void * cfg_data) { struct v3_southbridge * piix3 = (struct v3_southbridge *)V3_Malloc(sizeof(struct v3_southbridge)); struct vm_device * dev = NULL; + struct vm_device * pci = v3_find_dev(vm, (char *)cfg_data); + + if (!pci) { + PrintError("Could not find PCI device\n"); + return -1; + } piix3->pci_bus = pci; piix3->type = V3_SB_PIIX3; - dev = v3_create_device("PIIX3", &dev_ops, piix3); + dev = v3_allocate_device("PIIX3", &dev_ops, piix3); + + if (v3_attach_device(vm, dev) == -1) { + PrintError("Could not attach device %s\n", "PIIX3"); + return -1; + } PrintDebug("Created PIIX3\n"); - return dev; + return setup_pci(dev); } + + +device_register("PIIX3", piix3_init) diff --git a/palacios/src/devices/ram_cd.c b/palacios/src/devices/ram_cd.c index fb88e37..b6a1bf6 100644 --- a/palacios/src/devices/ram_cd.c +++ b/palacios/src/devices/ram_cd.c @@ -19,6 +19,7 @@ #include #include +#include #include #ifndef DEBUG_IDE @@ -67,37 +68,27 @@ static struct v3_ide_cd_ops cd_ops = { }; -static int cd_init(struct vm_device * dev) { - struct cd_state * cd = (struct cd_state *)(dev->private_data); - if (v3_ide_register_cdrom(cd->ide, cd->bus, cd->drive, "RAM-CD", &cd_ops, dev) == -1) { - return -1; - } - - return 0; -} - -static int cd_deinit(struct vm_device * dev) { +static int cd_free(struct vm_device * dev) { return 0; } -static struct vm_device_ops dev_ops = { - .init = cd_init, - .deinit = cd_deinit, +static struct v3_device_ops dev_ops = { + .free = cd_free, .reset = NULL, .start = NULL, .stop = NULL, }; -struct vm_device * v3_create_ram_cd(struct vm_device * ide, - uint_t bus, uint_t drive, - addr_t ramdisk, uint32_t size) { + +static int cd_init(struct guest_info * vm, void * cfg_data) { struct cd_state * cd = NULL; + struct ram_cd_cfg * cfg = (struct ram_cd_cfg *)cfg_data; - if (size % ATAPI_BLOCK_SIZE) { + if (cfg->size % ATAPI_BLOCK_SIZE) { PrintError("CD image must be an integral of block size (ATAPI_BLOCK_SIZE=%d)\n", ATAPI_BLOCK_SIZE); - return NULL; + return -1; } cd = (struct cd_state *)V3_Malloc(sizeof(struct cd_state)); @@ -105,14 +96,33 @@ struct vm_device * v3_create_ram_cd(struct vm_device * ide, PrintDebug("Registering Ram CD at %p (size=%d)\n", (void *)ramdisk, size); - cd->disk_image = ramdisk; - cd->capacity = size; + cd->disk_image = cfg->ramdisk; + cd->capacity = cfg->size; + + cd->ide = v3_find_dev(vm, cfg->ide); + + if (cd->ide == 0) { + PrintError("Could not find backend %s\n", cfg->ide); + return -1; + } - cd->ide = ide; - cd->bus = bus; - cd->drive = drive; + cd->bus = cfg->bus; + cd->drive = cfg->drive; - struct vm_device * cd_dev = v3_create_device("RAM-CD", &dev_ops, cd); + struct vm_device * dev = v3_allocate_device("RAM-CD", &dev_ops, cd); + + if (v3_attach_device(vm, dev) == -1) { + PrintError("Could not attach device %s\n", "RAM-CD"); + return -1; + } + - return cd_dev; + if (v3_ide_register_cdrom(cd->ide, cd->bus, cd->drive, "RAM-CD", &cd_ops, dev) == -1) { + return -1; + } + + return 0; } + + +device_register("RAM-CD", cd_init) diff --git a/palacios/src/devices/ram_hd.c b/palacios/src/devices/ram_hd.c index 3bce4fc..49bf510 100644 --- a/palacios/src/devices/ram_hd.c +++ b/palacios/src/devices/ram_hd.c @@ -81,51 +81,62 @@ static struct v3_ide_hd_ops hd_ops = { }; -static int hd_init(struct vm_device * dev) { - struct hd_state * hd = (struct hd_state *)(dev->private_data); - - if (v3_ide_register_harddisk(hd->ide, hd->bus, hd->drive, "V3-RAM-HD", &hd_ops, dev) == -1) { - return -1; - } - - return 0; -} -static int hd_deinit(struct vm_device * dev) { +static int hd_free(struct vm_device * dev) { return 0; } -static struct vm_device_ops dev_ops = { - .init = hd_init, - .deinit = hd_deinit, +static struct v3_device_ops dev_ops = { + .free = hd_free, .reset = NULL, .start = NULL, .stop = NULL, }; -struct vm_device * v3_create_ram_hd(struct vm_device * ide, - uint_t bus, uint_t drive, - addr_t ramdisk, uint32_t size) { + + + +static int hd_init(struct guest_info * vm, void * cfg_data) { struct hd_state * hd = NULL; + struct ram_hd_cfg * cfg = (struct ram_hd_cfg *)cfg_data; - if (size % IDE_SECTOR_SIZE) { + if (cfg->size % IDE_SECTOR_SIZE) { PrintError("HD image must be an integral of sector size (IDE_SECTOR_SIZE=%d)\n", IDE_SECTOR_SIZE); - return NULL; + return -1; } hd = (struct hd_state *)V3_Malloc(sizeof(struct hd_state)); PrintDebug("Registering Ram HDD at %p (size=%d)\n", (void *)ramdisk, size); - hd->disk_image = ramdisk; - hd->capacity = size; + hd->disk_image = cfg->ramdisk; + hd->capacity = cfg->size; + + hd->ide = v3_find_dev(vm, cfg->ide); + + if (hd->ide == 0) { + PrintError("Could not find backend %s\n", cfg->ide); + return -1; + } - hd->ide = ide; - hd->bus = bus; - hd->drive = drive; + hd->bus = cfg->bus; + hd->drive = cfg->drive; - struct vm_device * hd_dev = v3_create_device("RAM-HD", &dev_ops, hd); + struct vm_device * dev = v3_allocate_device("RAM-HD", &dev_ops, hd); + + if (v3_attach_device(vm, dev) == -1) { + PrintError("Could not attach device %s\n", "RAM-HD"); + return -1; + } + - return hd_dev; + if (v3_ide_register_harddisk(hd->ide, hd->bus, hd->drive, "RAM-HD", &hd_ops, dev) == -1) { + return -1; + } + + return 0; } + + +device_register("RAM-HD", hd_init) diff --git a/palacios/src/devices/serial.c b/palacios/src/devices/serial.c index 49982fb..778050a 100644 --- a/palacios/src/devices/serial.c +++ b/palacios/src/devices/serial.c @@ -17,9 +17,8 @@ * redistribute, and modify it as specified in the file "V3VEE_LICENSE". */ -#include #include - +#include #define COM1_DATA_PORT 0x3f8 #define COM1_IRQ_ENABLE_PORT 0x3f9 @@ -490,56 +489,9 @@ static int init_serial_port(struct serial_port * com) { return 0; } -static int serial_init(struct vm_device * dev) { - struct serial_state * state = (struct serial_state *)dev->private_data; - - - init_serial_port(&(state->com1)); - init_serial_port(&(state->com2)); - init_serial_port(&(state->com3)); - init_serial_port(&(state->com4)); - - v3_dev_hook_io(dev, COM1_DATA_PORT, &read_data_port, &write_data_port); - v3_dev_hook_io(dev, COM1_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM1_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM1_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM1_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM1_LINE_STATUS_PORT, &read_status_port, &write_status_port); - v3_dev_hook_io(dev, COM1_MODEM_STATUS_PORT, &read_status_port, &write_status_port); - v3_dev_hook_io(dev, COM1_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port); - - v3_dev_hook_io(dev, COM2_DATA_PORT, &read_data_port, &write_data_port); - v3_dev_hook_io(dev, COM2_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM2_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM2_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM2_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM2_LINE_STATUS_PORT, &read_status_port, &write_status_port); - v3_dev_hook_io(dev, COM2_MODEM_STATUS_PORT, &read_status_port, &write_status_port); - v3_dev_hook_io(dev, COM2_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port); - - v3_dev_hook_io(dev, COM3_DATA_PORT, &read_data_port, &write_data_port); - v3_dev_hook_io(dev, COM3_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM3_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM3_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM3_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM3_LINE_STATUS_PORT, &read_status_port, &write_status_port); - v3_dev_hook_io(dev, COM3_MODEM_STATUS_PORT, &read_status_port, &write_status_port); - v3_dev_hook_io(dev, COM3_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port); - - v3_dev_hook_io(dev, COM4_DATA_PORT, &read_data_port, &write_data_port); - v3_dev_hook_io(dev, COM4_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM4_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM4_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM4_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM4_LINE_STATUS_PORT, &read_status_port, &write_status_port); - v3_dev_hook_io(dev, COM4_MODEM_STATUS_PORT, &read_status_port, &write_status_port); - v3_dev_hook_io(dev, COM4_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port); - - return 0; -} -static int serial_deinit(struct vm_device * dev) { +static int serial_free(struct vm_device * dev) { v3_dev_unhook_io(dev, COM1_DATA_PORT); @@ -583,21 +535,76 @@ static int serial_deinit(struct vm_device * dev) { -static struct vm_device_ops dev_ops = { - .init = serial_init, - .deinit = serial_deinit, +static struct v3_device_ops dev_ops = { + .free = serial_free, .reset = NULL, .start = NULL, .stop = NULL, }; -struct vm_device * v3_create_serial(int num_ports) { + + +static int serial_init(struct guest_info * vm, void * cfg_data) { struct serial_state * state = NULL; + state = (struct serial_state *)V3_Malloc(sizeof(struct serial_state)); + V3_ASSERT(state != NULL); - struct vm_device * device = v3_create_device("Serial UART", &dev_ops, state); + struct vm_device * dev = v3_allocate_device("SERIAL", &dev_ops, state); + + + if (v3_attach_device(vm, dev) == -1) { + PrintError("Could not attach device %s\n", "SERIAL"); + return -1; + } + + + + init_serial_port(&(state->com1)); + init_serial_port(&(state->com2)); + init_serial_port(&(state->com3)); + init_serial_port(&(state->com4)); + + v3_dev_hook_io(dev, COM1_DATA_PORT, &read_data_port, &write_data_port); + v3_dev_hook_io(dev, COM1_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM1_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM1_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM1_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM1_LINE_STATUS_PORT, &read_status_port, &write_status_port); + v3_dev_hook_io(dev, COM1_MODEM_STATUS_PORT, &read_status_port, &write_status_port); + v3_dev_hook_io(dev, COM1_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port); + + v3_dev_hook_io(dev, COM2_DATA_PORT, &read_data_port, &write_data_port); + v3_dev_hook_io(dev, COM2_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM2_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM2_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM2_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM2_LINE_STATUS_PORT, &read_status_port, &write_status_port); + v3_dev_hook_io(dev, COM2_MODEM_STATUS_PORT, &read_status_port, &write_status_port); + v3_dev_hook_io(dev, COM2_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port); + + v3_dev_hook_io(dev, COM3_DATA_PORT, &read_data_port, &write_data_port); + v3_dev_hook_io(dev, COM3_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM3_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM3_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM3_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM3_LINE_STATUS_PORT, &read_status_port, &write_status_port); + v3_dev_hook_io(dev, COM3_MODEM_STATUS_PORT, &read_status_port, &write_status_port); + v3_dev_hook_io(dev, COM3_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port); - return device; + v3_dev_hook_io(dev, COM4_DATA_PORT, &read_data_port, &write_data_port); + v3_dev_hook_io(dev, COM4_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM4_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM4_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM4_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM4_LINE_STATUS_PORT, &read_status_port, &write_status_port); + v3_dev_hook_io(dev, COM4_MODEM_STATUS_PORT, &read_status_port, &write_status_port); + v3_dev_hook_io(dev, COM4_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port); + + return 0; } + + +device_register("SERIAL", serial_init) diff --git a/palacios/src/devices/simple_pic.c b/palacios/src/devices/simple_pic.c index 828b588..96907df 100644 --- a/palacios/src/devices/simple_pic.c +++ b/palacios/src/devices/simple_pic.c @@ -17,7 +17,7 @@ * redistribute, and modify it as specified in the file "V3VEE_LICENSE". */ -#include + #include #include #include @@ -60,39 +60,42 @@ static struct intr_ctrl_ops intr_ops = { -static int pic_init_device(struct vm_device * dev) { - struct pic_internal * data = (struct pic_internal *)dev->private_data; - v3_register_intr_controller(dev->vm, &intr_ops, data); - data->pending_irq = 0; - - return 0; -} -static int pic_deinit_device(struct vm_device * dev) { +static int pic_free(struct vm_device * dev) { return 0; } - -static struct vm_device_ops dev_ops = { - .init = pic_init_device, - .deinit = pic_deinit_device, +static struct v3_device_ops dev_ops = { + .free = pic_free, .reset = NULL, .start = NULL, .stop = NULL }; -struct vm_device * v3_create_simple_pic() { + + +static int pic_init(struct guest_info * vm, void * cfg_data) { struct pic_internal * state = NULL; state = (struct pic_internal *)V3_Malloc(sizeof(struct pic_internal)); V3_ASSERT(state != NULL); - struct vm_device * pic_dev = v3_create_device("Simple Pic", &dev_ops, state); + struct vm_device * dev = v3_allocate_device("SIMPLE_PIC", &dev_ops, state); + + if (v3_attach_device(vm, dev) == -1) { + PrintError("Could not attach device %s\n", "SIMPLE_PIC"); + return -1; + } + + v3_register_intr_controller(vm, &intr_ops, state); + state->pending_irq = 0; - return pic_dev; + return 0; } + +device_register("SIMPLE_PIC", pic_init) diff --git a/palacios/src/devices/sym_swap.c b/palacios/src/devices/sym_swap.c index 706d1c5..ea303e5 100644 --- a/palacios/src/devices/sym_swap.c +++ b/palacios/src/devices/sym_swap.c @@ -18,8 +18,7 @@ */ #include - -#include +#include #include @@ -31,20 +30,16 @@ struct swap_state { }; -static int swap_init(struct vm_device * dev) { - return -1; -} -static int swap_deinit(struct vm_device * dev) { +static int swap_free(struct vm_device * dev) { return -1; } -static struct vm_device_ops dev_ops = { - .init = swap_init, - .deinit = swap_deinit, +static struct v3_device_ops dev_ops = { + .free = swap_free, .reset = NULL, .start = NULL, .stop = NULL, @@ -52,19 +47,37 @@ static struct vm_device_ops dev_ops = { -struct vm_device * v3_create_swap(struct vm_device * virtio_blk) { + +static int swap_init(struct guest_info * vm, void * cfg_data) { struct swap_state * swap = NULL; + struct vm_device * virtio_blk = v3_find_dev(vm, (char *)cfg_data); + + if (!virtio_blk) { + PrintError("could not find Virtio backend\n"); + return -1; + } PrintDebug("Creating Swap Device\n"); if (virtio_blk == NULL) { PrintError("Swap device requires a virtio block device\n"); - return NULL; + return -1; } swap = (struct swap_state *)V3_Malloc(sizeof(struct swap_state)); swap->blk_dev = virtio_blk; - return v3_create_device("SYM_SWAP", &dev_ops, swap); + struct vm_device * dev = v3_allocate_device("SYM_SWAP", &dev_ops, swap); + + if (v3_attach_device(vm, dev) == -1) { + PrintError("Could not attach device %s\n", "SYM_SWAP"); + return -1; + } + + return 0; } + + + +device_register("SYM_SWAP", swap_init) diff --git a/palacios/src/devices/timer.c b/palacios/src/devices/timer.c index e0a8d70..31c47de 100644 --- a/palacios/src/devices/timer.c +++ b/palacios/src/devices/timer.c @@ -17,9 +17,9 @@ * redistribute, and modify it as specified in the file "V3VEE_LICENSE". */ -#include -#include +#include +#include #define TIMER_IRQ 32 @@ -36,21 +36,16 @@ struct timer_state { } */ -static int timer_init(struct vm_device * dev) { - //dev_hook_irq(dev, TIMER_IRQ, &irq_handler); - return 0; -} -static int timer_deinit(struct vm_device * dev) { +static int timer_free(struct vm_device * dev) { return 0; } -static struct vm_device_ops dev_ops = { - .init = timer_init, - .deinit = timer_deinit, +static struct v3_device_ops dev_ops = { + .free = timer_free, .reset = NULL, .start = NULL, .stop = NULL, @@ -58,13 +53,23 @@ static struct vm_device_ops dev_ops = { }; -struct vm_device * v3_create_timer() { +static int timer_init(struct guest_info * vm, void * cfg_data) { struct timer_state * timer = NULL; timer = (struct timer_state *)V3_Malloc( sizeof(struct timer_state)); V3_ASSERT(timer != NULL); - struct vm_device * dev = v3_create_device("Timer", &dev_ops, timer); - - return dev; + struct vm_device * dev = v3_allocate_device("TIMER", &dev_ops, timer); + + if (v3_attach_device(vm, dev) == -1) { + PrintError("Could not attach device %s\n", "TIMER"); + return -1; + } + + + + return -1; } + + +device_register("TIMER", timer_init) diff --git a/palacios/src/palacios/vm_dev.c b/palacios/src/palacios/vm_dev.c deleted file mode 100644 index 9078f66..0000000 --- a/palacios/src/palacios/vm_dev.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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 - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Jack Lange - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - - -#include -#include - - - -static struct vm_device * v3_allocate_device() { - struct vm_device * dev = NULL; - dev = (struct vm_device*)V3_Malloc(sizeof(struct vm_device)); - - V3_ASSERT(dev != NULL); - - dev->ops = NULL; - memset(dev->name, 0, 32); - dev->vm = NULL; - dev->private_data = NULL; - - return dev; -} - -struct vm_device * v3_create_device(char * name, struct vm_device_ops * ops, void * private_data) { - struct vm_device * dev = v3_allocate_device(); - - strncpy(dev->name, name, 32); - dev->ops = ops; - dev->private_data = private_data; - - return dev; -} - -void v3_free_device(struct vm_device * dev) { - V3_Free(dev); -} - diff --git a/palacios/src/palacios/vmm.c b/palacios/src/palacios/vmm.c index 1b191d0..a20399b 100644 --- a/palacios/src/palacios/vmm.c +++ b/palacios/src/palacios/vmm.c @@ -49,6 +49,9 @@ void Init_V3(struct v3_os_hooks * hooks, struct v3_ctrl_ops * vmm_ops) { os_hooks = hooks; v3_cpu_type = V3_INVALID_CPU; + // Register all the possible device types + v3_init_devices(); + #ifdef INSTRUMENT_VMM v3_init_instrumentation(); diff --git a/palacios/src/palacios/vmm_config.c b/palacios/src/palacios/vmm_config.c index f917f67..f226ea5 100644 --- a/palacios/src/palacios/vmm_config.c +++ b/palacios/src/palacios/vmm_config.c @@ -27,25 +27,13 @@ #include -#include -#include -#include -#include -#include + #include #include #include #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include #include @@ -58,7 +46,7 @@ static int setup_memory_map(struct guest_info * info, struct v3_vm_config * config_ptr); static int setup_devices(struct guest_info * info, struct v3_vm_config * config_ptr); -static struct vm_device * configure_generic(struct guest_info * info, struct v3_vm_config * config_ptr); +static int configure_generic(struct guest_info * info, struct v3_vm_config * config_ptr); @@ -211,68 +199,71 @@ static int setup_memory_map(struct guest_info * info, struct v3_vm_config * conf static int setup_devices(struct guest_info * info, struct v3_vm_config * config_ptr) { - struct vm_device * ide = NULL; - struct vm_device * primary_disk = NULL; - struct vm_device * secondary_disk = NULL; + + v3_create_device(info, "8259A", NULL); + v3_create_device(info, "KEYBOARD", NULL); + v3_create_device(info, "8254_PIT", NULL); + v3_create_device(info, "BOCHS_DEBUG", NULL); + v3_create_device(info, "OS_DEBUG", NULL); + v3_create_device(info, "LAPIC", NULL); + v3_create_device(info, "IOAPIC", "LAPIC"); + v3_create_device(info, "PARANET", NULL); - struct vm_device * pci = NULL; - struct vm_device * northbridge = NULL; - struct vm_device * southbridge = NULL; + int use_generic = USE_GENERIC; - struct vm_device * nvram = NULL; - struct vm_device * pic = v3_create_pic(); - struct vm_device * keyboard = v3_create_keyboard(); - struct vm_device * pit = v3_create_pit(); - struct vm_device * bochs_debug = v3_create_bochs_debug(); - struct vm_device * os_debug = v3_create_os_debug(); - struct vm_device * apic = v3_create_apic(); - struct vm_device * ioapic = v3_create_io_apic(apic); - struct vm_device * para_net = v3_create_para_net(); + if (config_ptr->enable_pci == 1) { + struct ide_cfg ide_config = {"PCI", "PIIX3"}; + + v3_create_device(info, "PCI", NULL); + v3_create_device(info, "i440FX", "PCI"); + v3_create_device(info, "PIIX3", "PCI"); + + v3_create_device(info, "IDE", &ide_config); + } else { + v3_create_device(info, "IDE", NULL); - //struct vm_device * serial = v3_create_serial(); - struct vm_device * generic = NULL; + } - int use_generic = USE_GENERIC; - if (config_ptr->enable_pci == 1) { - pci = v3_create_pci(); - northbridge = v3_create_i440fx(pci); - southbridge = v3_create_piix3(pci); - ide = v3_create_ide(pci, southbridge); - } else { - ide = v3_create_ide(NULL, NULL); - } - nvram = v3_create_nvram(ide); if (config_ptr->pri_disk_type != NONE) { if (config_ptr->pri_disk_type == CDROM) { if (config_ptr->pri_disk_con == RAM) { + struct ram_cd_cfg cfg = {"IDE", 0, 0, + (addr_t)(config_ptr->pri_disk_info.ram.data_ptr), + config_ptr->pri_disk_info.ram.size}; + PrintDebug("Creating RAM CD\n"); - primary_disk = v3_create_ram_cd(ide, 0, 0, - (addr_t)(config_ptr->pri_disk_info.ram.data_ptr), - config_ptr->pri_disk_info.ram.size); + + v3_create_device(info, "RAM-CD", &cfg); } else if (config_ptr->pri_disk_con == NETWORK) { + struct net_cd_cfg cfg = {"IDE", 0, 0, + config_ptr->pri_disk_info.net.ip_str, + config_ptr->pri_disk_info.net.port, + config_ptr->pri_disk_info.net.disk_name}; PrintDebug("Creating NET CD\n"); - primary_disk = v3_create_net_cd(ide, 0, 0, - config_ptr->pri_disk_info.net.ip_str, - config_ptr->pri_disk_info.net.port, - config_ptr->pri_disk_info.net.disk_name); + + v3_create_device(info, "NET-CD", &cfg); } } else if (config_ptr->pri_disk_type == HARDDRIVE) { if (config_ptr->pri_disk_con == RAM) { + struct ram_hd_cfg cfg = {"IDE", 0, 0, + (addr_t)(config_ptr->pri_disk_info.ram.data_ptr), + config_ptr->pri_disk_info.ram.size}; + PrintDebug("Creating RAM HD\n"); - primary_disk = v3_create_ram_hd(ide, 0, 0, - (addr_t)(config_ptr->pri_disk_info.ram.data_ptr), - config_ptr->pri_disk_info.ram.size); + + v3_create_device(info, "RAM-HD", &cfg); } else if (config_ptr->pri_disk_con == NETWORK) { + struct net_hd_cfg cfg = {"IDE", 0, 0, + config_ptr->pri_disk_info.net.ip_str, + config_ptr->pri_disk_info.net.port, + config_ptr->pri_disk_info.net.disk_name}; PrintDebug("Creating NET HD\n"); - primary_disk = v3_create_net_hd(ide, 0, 0, - config_ptr->pri_disk_info.net.ip_str, - config_ptr->pri_disk_info.net.port, - config_ptr->pri_disk_info.net.disk_name); + v3_create_device(info, "NET-HD", &cfg); } } } @@ -282,29 +273,35 @@ static int setup_devices(struct guest_info * info, struct v3_vm_config * config_ if (config_ptr->sec_disk_type != NONE) { if (config_ptr->sec_disk_type == CDROM) { if (config_ptr->sec_disk_con == RAM) { + struct ram_cd_cfg cfg = {"IDE", 0, 1, + (addr_t)(config_ptr->sec_disk_info.ram.data_ptr), + config_ptr->sec_disk_info.ram.size}; + PrintDebug("Creating RAM CD\n"); - secondary_disk = v3_create_ram_cd(ide, 0, 1, - (addr_t)(config_ptr->sec_disk_info.ram.data_ptr), - config_ptr->sec_disk_info.ram.size); + v3_create_device(info, "RAM-CD", &cfg); } else if (config_ptr->sec_disk_con == NETWORK) { + struct net_cd_cfg cfg = {"IDE", 0, 1, + config_ptr->sec_disk_info.net.ip_str, + config_ptr->sec_disk_info.net.port, + config_ptr->sec_disk_info.net.disk_name}; + PrintDebug("Creating NET CD\n"); - secondary_disk = v3_create_net_cd(ide, 0, 1, - config_ptr->sec_disk_info.net.ip_str, - config_ptr->sec_disk_info.net.port, - config_ptr->sec_disk_info.net.disk_name); + v3_create_device(info, "NET-CD", &cfg); } } else if (config_ptr->sec_disk_type == HARDDRIVE) { if (config_ptr->sec_disk_con == RAM) { + struct ram_hd_cfg cfg = {"IDE", 0, 1, + (addr_t)(config_ptr->sec_disk_info.ram.data_ptr), + config_ptr->sec_disk_info.ram.size}; PrintDebug("Creating RAM HD\n"); - secondary_disk = v3_create_ram_hd(ide, 0, 1, - (addr_t)(config_ptr->sec_disk_info.ram.data_ptr), - config_ptr->sec_disk_info.ram.size); + v3_create_device(info, "RAM-HD", &cfg); } else if (config_ptr->sec_disk_con == NETWORK) { + struct net_hd_cfg cfg = {"IDE", 0, 1, + config_ptr->sec_disk_info.net.ip_str, + config_ptr->sec_disk_info.net.port, + config_ptr->sec_disk_info.net.disk_name}; PrintDebug("Creating NET HD\n"); - secondary_disk = v3_create_net_hd(ide, 0, 1, - config_ptr->sec_disk_info.net.ip_str, - config_ptr->sec_disk_info.net.port, - config_ptr->sec_disk_info.net.disk_name); + v3_create_device(info, "NET-HD", &cfg); } } } @@ -312,49 +309,11 @@ static int setup_devices(struct guest_info * info, struct v3_vm_config * config_ if (use_generic) { - generic = configure_generic(info, config_ptr); - } - - - v3_attach_device(info, pic); - v3_attach_device(info, pit); - v3_attach_device(info, keyboard); - // v3_attach_device(info, serial); - v3_attach_device(info, bochs_debug); - v3_attach_device(info, os_debug); - - v3_attach_device(info, apic); - v3_attach_device(info, ioapic); - - v3_attach_device(info, para_net); - - if (config_ptr->enable_pci == 1) { - PrintDebug("Attaching PCI\n"); - v3_attach_device(info, pci); - PrintDebug("Attaching Northbridge\n"); - v3_attach_device(info, northbridge); - PrintDebug("Attaching Southbridge\n"); - v3_attach_device(info, southbridge); - } - - PrintDebug("Attaching IDE\n"); - v3_attach_device(info, ide); - - if (primary_disk != NULL) { - v3_attach_device(info, primary_disk); - } - - if (secondary_disk != NULL) { - v3_attach_device(info, secondary_disk); - } - - if (use_generic) { - // Important that this be attached last! - v3_attach_device(info, generic); + configure_generic(info, config_ptr); } - // This should go last because it contains the hardware state - v3_attach_device(info, nvram); + // This should go last because it requires information about the Harddrives + v3_create_device(info, "NVRAM", "IDE"); PrintDebugDevMgr(info); @@ -364,12 +323,18 @@ static int setup_devices(struct guest_info * info, struct v3_vm_config * config_ - -static struct vm_device * configure_generic(struct guest_info * info, struct v3_vm_config * config_ptr) { +static int configure_generic(struct guest_info * info, struct v3_vm_config * config_ptr) { PrintDebug("Creating Generic Device\n"); - struct vm_device * generic = v3_create_generic(); + v3_create_device(info, "GENERIC", NULL); + struct vm_device * generic = v3_find_dev(info, "GENERIC"); + + if (!generic) { + PrintError("Could not find generic device\n"); + return -1; + } + // port 0x92: A20 enable/disable (bit 2) (This causes an MMU flush) @@ -474,5 +439,5 @@ static struct vm_device * configure_generic(struct guest_info * info, struct v3 // v3_generic_add_port_range(generic, 0x378, 0x400, GENERIC_PRINT_AND_IGNORE); - return generic; + return 0; } diff --git a/palacios/src/palacios/vmm_dev_mgr.c b/palacios/src/palacios/vmm_dev_mgr.c index f4c8d62..fcbd93c 100644 --- a/palacios/src/palacios/vmm_dev_mgr.c +++ b/palacios/src/palacios/vmm_dev_mgr.c @@ -17,7 +17,6 @@ * redistribute, and modify it as specified in the file "V3VEE_LICENSE". */ -#include #include #include #include @@ -30,9 +29,58 @@ #endif -//DEFINE_HASHTABLE_INSERT(insert_dev, const char *, struct vm_device *); -//DEFINE_HASHTABLE_SEARCH(find_dev, const char *, struct vm_device *); -//DEFINE_HASHTABLE_REMOVE(remove_dev, const char *, struct vm_device *, 0); +static struct hashtable * master_dev_table = NULL; + +static uint_t dev_hash_fn(addr_t key) { + char * name = (char *)key; + return v3_hash_buffer((uchar_t *)name, strlen(name)); +} + +static int dev_eq_fn(addr_t key1, addr_t key2) { + char * name1 = (char *)key1; + char * name2 = (char *)key2; + + return (strcmp(name1, name2) == 0); +} + + +int v3_init_devices() { + extern struct v3_device_info __start__v3_devices[]; + extern struct v3_device_info __stop__v3_devices[]; + struct v3_device_info * tmp_dev = __start__v3_devices; + int num_devices = (__stop__v3_devices - __start__v3_devices) / sizeof(struct v3_device_info); + int i = 0; + + + PrintDebug("%d Virtual devices registered with Palacios\n", num_devices); + PrintDebug("Start addres=%p, Stop address=%p\n", __start__v3_devices, __stop__v3_devices); + + master_dev_table = v3_create_htable(0, dev_hash_fn, dev_eq_fn); + + + + while (tmp_dev != __stop__v3_devices) { + PrintDebug("Device: %s\n", tmp_dev->name); + + if (v3_htable_search(master_dev_table, (addr_t)(tmp_dev->name))) { + PrintError("Multiple instance of device (%s)\n", tmp_dev->name); + return -1; + } + + if (v3_htable_insert(master_dev_table, + (addr_t)(tmp_dev->name), + (addr_t)(tmp_dev->init)) == 0) { + PrintError("Could not add device %s to master list\n", tmp_dev->name); + return -1; + } + + tmp_dev = &(__start__v3_devices[++i]); + } + + + return 0; +} + int v3_init_dev_mgr(struct guest_info * info) { struct vmm_dev_mgr * mgr = &(info->dev_mgr); @@ -40,7 +88,7 @@ int v3_init_dev_mgr(struct guest_info * info) { INIT_LIST_HEAD(&(mgr->dev_list)); mgr->num_devs = 0; - // mgr->dev_table = v3_create_htable(0, , ); + mgr->dev_table = v3_create_htable(0, dev_hash_fn, dev_eq_fn); return 0; } @@ -61,35 +109,42 @@ int v3_dev_mgr_deinit(struct guest_info * info) { -int v3_attach_device(struct guest_info * vm, struct vm_device * dev) { - struct vmm_dev_mgr *mgr= &(vm->dev_mgr); - - dev->vm = vm; +int v3_create_device(struct guest_info * info, const char * dev_name, void * cfg_data) { + int (*dev_init)(struct guest_info * info, void * cfg_data); - list_add(&(dev->dev_link), &(mgr->dev_list)); - mgr->num_devs++; + dev_init = (void *)v3_htable_search(master_dev_table, (addr_t)dev_name); + + if (dev_init == NULL) { + PrintError("Could not find device %s in master device table\n", dev_name); + return -1; + } - dev->ops->init(dev); + + if (dev_init(info, cfg_data) == -1) { + PrintError("Could not initialize Device %s\n", dev_name); + return -1; + } return 0; } -int v3_detach_device(struct vm_device * dev) { - struct vmm_dev_mgr * mgr = &(dev->vm->dev_mgr); - dev->ops->deinit(dev); +void v3_free_device(struct vm_device * dev) { + V3_Free(dev); +} - list_del(&(dev->dev_link)); - mgr->num_devs--; - dev->vm = NULL; - - return 0; -} +struct vm_device * v3_find_dev(struct guest_info * info, const char * dev_name) { + struct vmm_dev_mgr * mgr = &(info->dev_mgr); + return (struct vm_device *)v3_htable_search(mgr->dev_table, (addr_t)dev_name); +} +/****************************************************************/ +/* The remaining functions are called by the devices themselves */ +/****************************************************************/ /* IO HOOKS */ int v3_dev_hook_io(struct vm_device * dev, uint16_t port, @@ -108,6 +163,50 @@ int v3_dev_unhook_io(struct vm_device * dev, uint16_t port) { +int v3_detach_device(struct vm_device * dev) { + struct vmm_dev_mgr * mgr = &(dev->vm->dev_mgr); + + dev->ops->free(dev); + + list_del(&(dev->dev_link)); + mgr->num_devs--; + + dev->vm = NULL; + + return -1; +} + + +struct vm_device * v3_allocate_device(char * name, + struct v3_device_ops * ops, + void * private_data) { + struct vm_device * dev = NULL; + + dev = (struct vm_device*)V3_Malloc(sizeof(struct vm_device)); + + strncpy(dev->name, name, 32); + dev->ops = ops; + dev->private_data = private_data; + + dev->vm = NULL; + + return dev; +} + + +int v3_attach_device(struct guest_info * vm, struct vm_device * dev ) { + struct vmm_dev_mgr * mgr = &(vm->dev_mgr); + + dev->vm = vm; + + list_add(&(dev->dev_link), &(mgr->dev_list)); + mgr->num_devs++; + + + v3_htable_insert(mgr->dev_table, (addr_t)(dev->name), (addr_t)dev); + + return 0; +} #ifdef DEBUG_DEV_MGR