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.
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 \
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
+++ /dev/null
-/*
- * This file is part of the Palacios Virtual Machine Monitor developed
- * by the V3VEE Project with funding from the United States National
- * Science Foundation and the Department of Energy.
- *
- * The V3VEE Project is a joint project between Northwestern University
- * and the University of New Mexico. You can find out more at
- * http://www.v3vee.org
- *
- * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software. You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-
-#ifndef __DEVICES_8237_DMA_H__
-#define __DEVICES_8237_DMA_H__
-
-#ifdef __V3VEE__
-
-
-#include <palacios/vm_dev.h>
-
-struct vm_device * v3_create_dma();
-
-
-#endif // ! __V3VEE__
-
-#endif
+++ /dev/null
-/*
- * This file is part of the Palacios Virtual Machine Monitor developed
- * by the V3VEE Project with funding from the United States National
- * Science Foundation and the Department of Energy.
- *
- * The V3VEE Project is a joint project between Northwestern University
- * and the University of New Mexico. You can find out more at
- * http://www.v3vee.org
- *
- * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software. You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-#ifndef __DEVICES_8254_H__
-#define __DEVICES_8254_H__
-
-#ifdef __V3VEE__
-
-
-
-#include <palacios/vm_dev.h>
-
-struct vm_device * v3_create_pit();
-
-
-
-#endif // ! __V3VEE__
-
-#endif
+++ /dev/null
-/*
- * This file is part of the Palacios Virtual Machine Monitor developed
- * by the V3VEE Project with funding from the United States National
- * Science Foundation and the Department of Energy.
- *
- * The V3VEE Project is a joint project between Northwestern University
- * and the University of New Mexico. You can find out more at
- * http://www.v3vee.org
- *
- * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software. You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-#ifndef __DEVICES_8259A_H__
-#define __DEVICES_8259A_H__
-
-#ifdef __V3VEE__
-
-
-
-#include <palacios/vm_dev.h>
-
-struct vm_device * v3_create_pic();
-
-
-
-#endif // ! __V3VEE__
-
-#endif
#ifdef __V3VEE__
-#include <palacios/vm_dev.h>
-
-struct vm_device * v3_create_apic();
+#include <palacios/vmm_dev_mgr.h>
int v3_apic_raise_intr(struct vm_device * apic_dev, int intr_num);
+++ /dev/null
-/*
- * This file is part of the Palacios Virtual Machine Monitor developed
- * by the V3VEE Project with funding from the United States National
- * Science Foundation and the Department of Energy.
- *
- * The V3VEE Project is a joint project between Northwestern University
- * and the University of New Mexico. You can find out more at
- * http://www.v3vee.org
- *
- * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software. You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-#ifndef __DEVICES_BOCHS_DEBUG_H__
-#define __DEVICES_BOCHS_DEBUG_H__
-
-#ifdef __V3VEE__
-
-#include <palacios/vm_dev.h>
-
-struct vm_device * v3_create_bochs_debug();
-
-
-#endif // ! __V3VEE__
-
-#endif
#ifdef __V3VEE__
+#include <palacios/vmm_dev_mgr.h>
-#include <palacios/vm_dev.h>
-
//
// The generic device simply hooks ranges of ports, addresses, and irqs
// if they are not already hooked
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__
+++ /dev/null
-/*
- * This file is part of the Palacios Virtual Machine Monitor developed
- * by the V3VEE Project with funding from the United States National
- * Science Foundation and the Department of Energy.
- *
- * The V3VEE Project is a joint project between Northwestern University
- * and the University of New Mexico. You can find out more at
- * http://www.v3vee.org
- *
- * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software. You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-#ifndef __DEVICES_i440FX_H__
-#define __DEVICES_i440FX_H__
-
-#ifdef __V3VEE__
-
-#include <palacios/vm_dev.h>
-
-
-struct vm_device * v3_create_i440fx(struct vm_device * pci);
-
-
-#endif
-
-#endif
#define __DEVICES_IDE_H__
#ifdef __V3VEE__
-#include <palacios/vm_dev.h>
+
+
+struct ide_cfg {
+ char pci[32];
+ char southbridge[32];
+};
#define ATAPI_BLOCK_SIZE 2048
-struct vm_device * v3_create_ide();
-
int v3_ide_get_geometry(struct vm_device * ide_dev, int channel_num, int drive_num,
+++ /dev/null
-/*
- * This file is part of the Palacios Virtual Machine Monitor developed
- * by the V3VEE Project with funding from the United States National
- * Science Foundation and the Department of Energy.
- *
- * The V3VEE Project is a joint project between Northwestern University
- * and the University of New Mexico. You can find out more at
- * http://www.v3vee.org
- *
- * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software. You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-#ifndef __DEVICES_IO_APIC_H__
-#define __DEVICES_IO_APIC_H__
-
-
-#ifdef __V3VEE__
-
-#include <palacios/vm_dev.h>
-
-
-struct vm_device * v3_create_io_apic(struct vm_device * apic);
-
-
-#endif // ! __V3VEE__
-#endif
+++ /dev/null
-/*
- * This file is part of the Palacios Virtual Machine Monitor developed
- * by the V3VEE Project with funding from the United States National
- * Science Foundation and the Department of Energy.
- *
- * The V3VEE Project is a joint project between Northwestern University
- * and the University of New Mexico. You can find out more at
- * http://www.v3vee.org
- *
- * Copyright (c) 2008, Peter Dinda <pdinda@northwestern.edu>
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
- * All rights reserved.
- *
- * Author: Peter Dinda <pdinda@northwestern.edu>
- *
- * 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 <palacios/vm_dev.h>
-
-struct vm_device * v3_create_keyboard();
-
-
-
-#endif // ! __V3VEE__
-
-#endif
#ifdef __V3VEE__
-#include <palacios/vm_dev.h>
/* PCI Vendor IDs (from Qemu) */
-struct vm_device * v3_create_virtio_blk();
-
-
-
-
+++ /dev/null
-/*
- * This file is part of the Palacios Virtual Machine Monitor developed
- * by the V3VEE Project with funding from the United States National
- * Science Foundation and the Department of Energy.
- *
- * The V3VEE Project is a joint project between Northwestern University
- * and the University of New Mexico. You can find out more at
- * http://www.v3vee.org
- *
- * Copyright (c) 2009, Lei Xia <lxia@northwestern.edu>
- * Copyright (c) 2009, The V3VEE Project <http://www.v3vee.org>
- * All rights reserved.
- *
- * Author: Lei Xia <lxia@northwestern.edu>
- *
- * 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 <palacios/vm_dev.h>
-#include <palacios/vmm_types.h>
-
-
-struct vm_device * v3_create_ne2k();
-
-#endif
#ifdef __V3VEE__
-#include <palacios/vm_dev.h>
-
-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;
+};
#ifdef __V3VEE__
-#include <palacios/vm_dev.h>
-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;
+};
+++ /dev/null
-/*
- * This file is part of the Palacios Virtual Machine Monitor developed
- * by the V3VEE Project with funding from the United States National
- * Science Foundation and the Department of Energy.
- *
- * The V3VEE Project is a joint project between Northwestern University
- * and the University of New Mexico. You can find out more at
- * http://www.v3vee.org
- *
- * Copyright (c) 2008, Peter Dinda <pdinda@northwestern.edu>
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
- * All rights reserved.
- *
- * Author: Peter Dinda <pdinda@northwestern.edu>
- *
- * 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 <palacios/vm_dev.h>
-
-struct vm_device * v3_create_nvram(struct vm_device * ide);
-
-
-
-#endif // ! __V3VEE__
-
-#endif
+++ /dev/null
-/*
- * This file is part of the Palacios Virtual Machine Monitor developed
- * by the V3VEE Project with funding from the United States National
- * Science Foundation and the Department of Energy.
- *
- * The V3VEE Project is a joint project between Northwestern University
- * and the University of New Mexico. You can find out more at
- * http://www.v3vee.org
- *
- * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software. You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-#ifndef __DEVICES_OS_DEBUG_H__
-#define __DEVICES_OS_DEBUG_H__
-
-#ifdef __V3VEE__
-
-#include <palacios/vm_dev.h>
-
-struct vm_device * v3_create_os_debug();
-
-
-#endif // ! __V3VEE__
-
-#endif
+++ /dev/null
-/*
- * This file is part of the Palacios Virtual Machine Monitor developed
- * by the V3VEE Project with funding from the United States National
- * Science Foundation and the Department of Energy.
- *
- * The V3VEE Project is a joint project between Northwestern University
- * and the University of New Mexico. You can find out more at
- * http://www.v3vee.org
- *
- * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software. You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-#ifndef __DEVICES_PARA_NET_H__
-#define __DEVICES_PARA_NET_H__
-
-#ifdef __V3VEE__
-
-#include <palacios/vm_dev.h>
-
-struct vm_device * v3_create_para_net();
-
-
-#endif // ! __V3VEE__
-
-#endif
#ifdef __V3VEE__
-#include <palacios/vm_dev.h>
+
#include <palacios/vmm_types.h>
#include <palacios/vmm_rbtree.h>
-struct vm_device * v3_create_pci();
+
struct pci_device *
v3_pci_register_device(struct vm_device * pci,
+++ /dev/null
-/*
- * This file is part of the Palacios Virtual Machine Monitor developed
- * by the V3VEE Project with funding from the United States National
- * Science Foundation and the Department of Energy.
- *
- * The V3VEE Project is a joint project between Northwestern University
- * and the University of New Mexico. You can find out more at
- * http://www.v3vee.org
- *
- * Copyright (c) 2009, Lei Xia <lxia@northwestern.edu>
- * Copyright (c) 2009, Chang Seok Bae <jhuell@gmail.com>
- * Copyright (c) 2009, Jack Lange <jarusl@cs.northwestern.edu>
- * Copyright (c) 2009, The V3VEE Project <http://www.v3vee.org>
- * All rights reserved.
- *
- * Author: Lei Xia <lxia@northwestern.edu>
- * Chang Seok Bae <jhuell@gmail.com>
- * Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software. You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-#ifndef __DEVICES_PIIX3_H__
-#define __DEVICES_PIIX3_H__
-
-
-#ifdef __V3VEE__
-
-#include <palacios/vm_dev.h>
-
-
-struct vm_device * v3_create_piix3(struct vm_device * pci);
-
-#endif // ! __V3VEE__
-
-#endif
#ifdef __V3VEE__
-#include <palacios/vm_dev.h>
-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;
+};
#ifdef __V3VEE__
-#include <palacios/vm_dev.h>
-
-
-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;
+};
+++ /dev/null
-/*
- * This file is part of the Palacios Virtual Machine Monitor developed
- * by the V3VEE Project with funding from the United States National
- * Science Foundation and the Department of Energy.
- *
- * The V3VEE Project is a joint project between Northwestern University
- * and the University of New Mexico. You can find out more at
- * http://www.v3vee.org
- *
- * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software. You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-
-#ifndef __DEVICES_SERIAL_H__
-#define __DEVICES_SERIAL_H__
-
-#ifdef __V3VEE__
-
-
-
-#include <palacios/vm_dev.h>
-
-struct vm_device * v3_create_serial();
-
-
-
-#endif // ! __V3VEE__
-
-#endif
+++ /dev/null
-/*
- * This file is part of the Palacios Virtual Machine Monitor developed
- * by the V3VEE Project with funding from the United States National
- * Science Foundation and the Department of Energy.
- *
- * The V3VEE Project is a joint project between Northwestern University
- * and the University of New Mexico. You can find out more at
- * http://www.v3vee.org
- *
- * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software. You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-#ifndef __DEVICES_SIMPLE_PIC_H__
-#define __DEVICES_SIMPLE_PIC_H__
-
-#ifdef __V3VEE__
-
-
-#include <palacios/vm_dev.h>
-
-struct vm_device * v3_create_simple_pic();
-
-
-#endif // ! __V3VEE__
-
-#endif
+++ /dev/null
-/*
- * This file is part of the Palacios Virtual Machine Monitor developed
- * by the V3VEE Project with funding from the United States National
- * Science Foundation and the Department of Energy.
- *
- * The V3VEE Project is a joint project between Northwestern University
- * and the University of New Mexico. You can find out more at
- * http://www.v3vee.org
- *
- * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software. You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-
-
-#ifndef __DEVICES_SYM_SWAP_H__
-#define __DEVICES_SYM_SWAP_H__
-
-#ifdef __V3VEE__
-
-#include <palacios/vm_dev.h>
-
-
-
-struct vm_device * v3_create_swap(struct vm_device * virtio_blk);
-
-
-
-#endif
-
-#endif
+++ /dev/null
-/*
- * This file is part of the Palacios Virtual Machine Monitor developed
- * by the V3VEE Project with funding from the United States National
- * Science Foundation and the Department of Energy.
- *
- * The V3VEE Project is a joint project between Northwestern University
- * and the University of New Mexico. You can find out more at
- * http://www.v3vee.org
- *
- * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software. You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-#ifndef __DEVICES_TIMER_H__
-#define __DEVICES_TIMER_H__
-
-#ifdef __V3VEE__
-
-
-#include <palacios/vm_dev.h>
-
-struct vm_device * v3_create_timer();
-
-
-
-#endif // ! __V3VEE__
-
-#endif
+++ /dev/null
-/*
- * This file is part of the Palacios Virtual Machine Monitor developed
- * by the V3VEE Project with funding from the United States National
- * Science Foundation and the Department of Energy.
- *
- * The V3VEE Project is a joint project between Northwestern University
- * and the University of New Mexico. You can find out more at
- * http://www.v3vee.org
- *
- * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software. You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-#ifndef __VM_DEV_H
-#define __VM_DEV_H
-
-#ifdef __V3VEE__
-
-#include <palacios/vmm_types.h>
-#include <palacios/vmm_list.h>
-#include <palacios/vmm_dev_mgr.h>
-
-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
#include <palacios/vmm_string.h>
#include <palacios/vmm_hashtable.h>
-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;
+
+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
//
// 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
-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,
* redistribute, and modify it as specified in the file "V3VEE_LICENSE".
*/
-#include <devices/8254.h>
+
#include <palacios/vmm.h>
+#include <palacios/vmm_dev_mgr.h>
#include <palacios/vmm_time.h>
#include <palacios/vmm_util.h>
#include <palacios/vmm_intr.h>
}
-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);
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);
*/
-#include <devices/8259a.h>
+
#include <palacios/vmm_intr.h>
#include <palacios/vmm_types.h>
#include <palacios/vmm.h>
+#include <palacios/vmm_dev_mgr.h>
#ifndef DEBUG_PIC
#undef PrintDebug
-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;
}
-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);
};
-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);
}
-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)
*/
-#include <devices/bochs_debug.h>
+
#include <palacios/vmm.h>
+#include <palacios/vmm_dev_mgr.h>
#define BUF_SIZE 1024
}
-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);
-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);
-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);
-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,
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)
*/
#include <palacios/vmm.h>
-#include <devices/i440fx.h>
+#include <palacios/vmm_dev_mgr.h>
#include <devices/pci.h>
struct i440_state {
-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,
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)
-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");
}
-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);
-}
* redistribute, and modify it as specified in the file "V3VEE_LICENSE".
*/
-#include <devices/io_apic.h>
-#include <palacios/vmm.h>
+#include <palacios/vmm.h>
+#include <palacios/vmm_dev_mgr.h>
#include <devices/apic.h>
};
-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,
-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)
* redistribute, and modify it as specified in the file "V3VEE_LICENSE".
*/
-#include <devices/keyboard.h>
#include <palacios/vmm.h>
+#include <palacios/vmm_dev_mgr.h>
#include <palacios/vmm_types.h>
#include <palacios/vmm_ringbuffer.h>
-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);
-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,
-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;
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)
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;
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)
}
-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,
};
-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");
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");
}
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)
};
-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");
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)
*/
-#include <devices/nvram.h>
+#include <palacios/vmm_dev_mgr.h>
#include <palacios/vmm.h>
#include <palacios/vmm_types.h>
-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;
}
-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,
-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)
*/
-#include <devices/os_debug.h>
+
#include <palacios/vmm.h>
+#include <palacios/vmm_dev_mgr.h>
#include <palacios/vm_guest_mem.h>
#define BUF_SIZE 1024
}
-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);
-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)
* redistribute, and modify it as specified in the file "V3VEE_LICENSE".
*/
-#include <devices/para_net.h>
+
#include <palacios/vmm.h>
+#include <palacios/vmm_dev_mgr.h>
#include <palacios/vm_guest_mem.h>
#include <palacios/vmm_hypercall.h>
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)
-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++){
-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;
}
-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) {
* redistribute, and modify it as specified in the file "V3VEE_LICENSE".
*/
-#include <devices/piix3.h>
+
#include <palacios/vmm.h>
#include <devices/pci.h>
#include <devices/southbridge.h>
}
-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];
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)
#include <palacios/vmm.h>
#include <devices/ram_cd.h>
+#include <palacios/vmm_dev_mgr.h>
#include <devices/ide.h>
#ifndef DEBUG_IDE
};
-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));
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)
};
-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)
* redistribute, and modify it as specified in the file "V3VEE_LICENSE".
*/
-#include <devices/serial.h>
#include <palacios/vmm.h>
-
+#include <palacios/vmm_dev_mgr.h>
#define COM1_DATA_PORT 0x3f8
#define COM1_IRQ_ENABLE_PORT 0x3f9
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);
-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)
* redistribute, and modify it as specified in the file "V3VEE_LICENSE".
*/
-#include <devices/simple_pic.h>
+
#include <palacios/vmm_intr.h>
#include <palacios/vmm_types.h>
#include <palacios/vmm.h>
-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)
*/
#include <palacios/vmm.h>
-
-#include <devices/sym_swap.h>
+#include <palacios/vmm_dev_mgr.h>
#include <devices/lnx_virtio.h>
};
-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,
-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)
* redistribute, and modify it as specified in the file "V3VEE_LICENSE".
*/
-#include <devices/timer.h>
-#include <palacios/vmm.h>
+#include <palacios/vmm.h>
+#include <palacios/vmm_dev_mgr.h>
#define TIMER_IRQ 32
}
*/
-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,
};
-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)
+++ /dev/null
-/*
- * This file is part of the Palacios Virtual Machine Monitor developed
- * by the V3VEE Project with funding from the United States National
- * Science Foundation and the Department of Energy.
- *
- * The V3VEE Project is a joint project between Northwestern University
- * and the University of New Mexico. You can find out more at
- * http://www.v3vee.org
- *
- * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software. You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-
-#include <palacios/vm_dev.h>
-#include <palacios/vmm.h>
-
-
-
-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);
-}
-
os_hooks = hooks;
v3_cpu_type = V3_INVALID_CPU;
+ // Register all the possible device types
+ v3_init_devices();
+
#ifdef INSTRUMENT_VMM
v3_init_instrumentation();
#include <palacios/vmm_hypercall.h>
-#include <devices/serial.h>
-#include <devices/keyboard.h>
-#include <devices/8259a.h>
-#include <devices/8254.h>
-#include <devices/nvram.h>
+
#include <devices/generic.h>
#include <devices/ide.h>
#include <devices/ram_cd.h>
#include <devices/net_cd.h>
#include <devices/ram_hd.h>
#include <devices/net_hd.h>
-#include <devices/bochs_debug.h>
-#include <devices/os_debug.h>
-#include <devices/apic.h>
-#include <devices/io_apic.h>
-#include <devices/para_net.h>
-#include <devices/pci.h>
-#include <devices/i440fx.h>
-#include <devices/piix3.h>
#include <palacios/vmm_host_events.h>
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);
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);
}
}
}
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);
}
}
}
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);
-
-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)
// v3_generic_add_port_range(generic, 0x378, 0x400, GENERIC_PRINT_AND_IGNORE);
- return generic;
+ return 0;
}
* redistribute, and modify it as specified in the file "V3VEE_LICENSE".
*/
-#include <palacios/vm_dev.h>
#include <palacios/vmm_dev_mgr.h>
#include <palacios/vm_guest.h>
#include <palacios/vmm.h>
#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);
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;
}
-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,
+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