Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


updated the pci and IDE configuration.
Jack Lange [Wed, 8 Apr 2009 00:22:01 +0000 (19:22 -0500)]
Made the IDE/PCI system configurable via the config struct.
Starting to add the north/south bridges as virtual devices
DMA still not working....

palacios/build/Makefile
palacios/include/devices/piix3.h [new file with mode: 0644]
palacios/include/palacios/vmm.h
palacios/src/devices/ata.h
palacios/src/devices/ide.c
palacios/src/devices/pci.c
palacios/src/devices/piix3.c [new file with mode: 0644]
palacios/src/devices/ram_hd.c
palacios/src/palacios/svm_halt.c
palacios/src/palacios/svm_handler.c
palacios/src/palacios/vmm_config.c

index 46fcc40..4e8c8e3 100644 (file)
@@ -332,6 +332,8 @@ DEVICES_OBJS := \
        devices/ide.o \
        devices/ram_cd.o \
        devices/ram_hd.o \
+       devices/i440fx.o \
+       devices/piix3.o \
 
 #      devices/cdrom.o \
 #      devices/ramdisk.o \
diff --git a/palacios/include/devices/piix3.h b/palacios/include/devices/piix3.h
new file mode 100644 (file)
index 0000000..db390a8
--- /dev/null
@@ -0,0 +1,37 @@
+/* 
+ * 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
index 4a4ed79..f5bad18 100644 (file)
@@ -275,7 +275,11 @@ struct v3_vm_config {
     int enable_profiling;
     int enable_nested_paging;
 
-    int use_ramdisk;
+    int enable_pci;
+    
+    int use_ram_cd;
+    int use_ram_hd;
+
     void * ramdisk;
     int ramdisk_size;
 };
index 1e8df43..e31377a 100644 (file)
@@ -56,10 +56,10 @@ static void ata_identify_device(struct ide_drive * drive) {
     // 32 bits access
     drive_id->dword_io = 1;
 
-#if 0
+
     // enable DMA access
     drive_id->dma_enable = 1;
-#endif
+
     // enable LBA access
     drive_id->lba_enable = 1;
     
@@ -69,19 +69,21 @@ static void ata_identify_device(struct ide_drive * drive) {
     // Drive Capacity (48 bit LBA)
     drive_id->lba_capacity_2 = drive->hd_ops->get_capacity(drive->private_data);
 
-#if 0
+
     // lower byte is the maximum multiple sector size...
     drive_id->rw_multiples = 0x8000 | MAX_MULT_SECTORS;
-#endif
 
-#if 0
+
+
     // words 64-70, 54-58 valid
     drive_id->field_valid = 0x0007; // DMA + pkg cmd valid
-#endif
+
 
     // copied from CFA540A
-    drive_id->buf[63] = 0x0103; // variable (DMA stuff)
+    // drive_id->buf[63] = 0x0103; // variable (DMA stuff)
     //drive_id->buf[63] = 0x0000; // variable (DMA stuff)
+    drive_id->buf[63] = 0x0007;
+
     
     //    drive_id->buf[64] = 0x0001; // PIO
     drive_id->buf[65] = 0x00b4;
@@ -95,12 +97,12 @@ static void ata_identify_device(struct ide_drive * drive) {
     //    drive_id->buf[80] = 0x1e; // supports up to ATA/ATAPI-4
     drive_id->major_rev_num = 0x0040; // supports up to ATA/ATAPI-6
 
-#if 0
+
     drive_id->buf[83] |= 0x0400; // supports 48 bit LBA
 
 
     drive_id->dma_ultra = 0x2020; // Ultra_DMA_Mode_5_Selected | Ultra_DMA_Mode_5_Supported;
-#endif
+
 }
 
 
index bf85ba1..562688f 100644 (file)
@@ -224,6 +224,7 @@ struct ide_channel {
 struct ide_internal {
     struct ide_channel channels[2];
     struct vm_device * pci;
+    struct vm_device * southbridge;
     struct pci_device * busmaster_pci;
 };
 
@@ -1164,73 +1165,73 @@ static int pci_config_update(struct pci_device * pci_dev, uint_t reg_num, int le
 
 static int init_ide_state(struct vm_device * dev) {
     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
-    struct v3_pci_bar bars[6];
-    struct pci_device * pci_dev = NULL;
     int i, j;
 
-    for (i = 0; i < 2; i++) {
+
+    /* 
+       Check if the PIIX 3 actually represents both IDE channels in a single PCI entry */
+
+    for (i = 0; i < 1; i++) {
        init_channel(&(ide->channels[i]));
 
        // JRL: this is a terrible hack...
        ide->channels[i].irq = PRI_DEFAULT_IRQ + i;
 
-       for (j = 0; j < 6; j++) {
-           bars[j].type = PCI_BAR_NONE;
-       }
 
+       if (ide->pci) {
+           struct v3_pci_bar bars[6];
+           struct pci_device * pci_dev = NULL;
 
-       bars[4].type = PCI_BAR_IO;
-       bars[4].default_base_port = PRI_DEFAULT_DMA_PORT + (i * 0x8);
-       bars[4].num_ports = 8;
-       
-       if (i == 0) {
-           bars[4].io_read = read_pri_dma_port;
-           bars[4].io_write = write_pri_dma_port;
-       } else {
-           bars[4].io_read = read_sec_dma_port;
-           bars[4].io_write = write_sec_dma_port;
-       }
-
-       pci_dev = v3_pci_register_device(ide->pci, PCI_STD_DEVICE, 0, "V3_IDE", -1, bars,
-                                        pci_config_update, NULL, NULL, dev);
+           for (j = 0; j < 6; j++) {
+               bars[j].type = PCI_BAR_NONE;
+           }
 
-       if (pci_dev == NULL) {
-           PrintError("Failed to register IDE BUS %d with PCI\n", i); 
-           return -1;
-       }
 
-       ide->channels[i].pci_dev = pci_dev;
+           bars[4].type = PCI_BAR_IO;
+           bars[4].default_base_port = PRI_DEFAULT_DMA_PORT + (i * 0x8);
+           bars[4].num_ports = 8;
+           
+           if (i == 0) {
+               bars[4].io_read = read_pri_dma_port;
+               bars[4].io_write = write_pri_dma_port;
+           } else {
+               bars[4].io_read = read_sec_dma_port;
+               bars[4].io_write = write_sec_dma_port;
+           }
 
-       pci_dev->config_header.vendor_id = 0x1095;
-       pci_dev->config_header.device_id = 0x0646;
-       pci_dev->config_header.revision = 0x8f07;
-       pci_dev->config_header.subclass = 0x01;
-       pci_dev->config_header.class = 0x01;
+           pci_dev = v3_pci_register_device(ide->pci, PCI_STD_DEVICE, 0, "V3_IDE", -1, bars,
+                                            pci_config_update, NULL, NULL, dev);
 
-       pci_dev->config_header.intr_line = PRI_DEFAULT_IRQ + i;
-       pci_dev->config_header.intr_pin = 1;
-    }
+           if (pci_dev == NULL) {
+               PrintError("Failed to register IDE BUS %d with PCI\n", i); 
+               return -1;
+           }
 
+           ide->channels[i].pci_dev = pci_dev;
 
+           /* This is for CMD646 devices 
+              pci_dev->config_header.vendor_id = 0x1095;
+              pci_dev->config_header.device_id = 0x0646;
+              pci_dev->config_header.revision = 0x8f07;
+           */
+           pci_dev->config_header.vendor_id = 0x8086;
+           pci_dev->config_header.device_id = 0x7010;
+           pci_dev->config_header.revision = 0x8000;
+           
+           pci_dev->config_header.subclass = 0x01;
+           pci_dev->config_header.class = 0x01;
+           
+           
+           pci_dev->config_header.command = 0;
+           pci_dev->config_header.status = 0x0280;
+           
+           //      pci_dev->config_header.intr_line = PRI_DEFAULT_IRQ + i;
+           //      pci_dev->config_header.intr_pin = 1;
+       }
+       
 
-    /* Register PIIX3 Busmaster PCI device */
-    for (j = 0; j < 6; j++) {
-       bars[j].type = PCI_BAR_NONE;
     }
 
-    pci_dev = v3_pci_register_device(ide->pci, PCI_STD_DEVICE, 0, "PIIX3 IDE", -1, bars,
-                                    NULL, NULL, NULL, dev);
-    
-    
-    ide->busmaster_pci = pci_dev;
-
-    pci_dev->config_header.vendor_id = 0x8086;
-    pci_dev->config_header.device_id = 0x7010;
-    pci_dev->config_header.revision = 0x80;
-    pci_dev->config_header.subclass = 0x01;
-    pci_dev->config_header.class = 0x01;
-
-
     return 0;
 }
 
@@ -1315,11 +1316,12 @@ static struct vm_device_ops dev_ops = {
 };
 
 
-struct vm_device *  v3_create_ide(struct vm_device * pci) {
+struct vm_device *  v3_create_ide(struct vm_device * pci, struct vm_device * southbridge) {
     struct ide_internal * ide  = (struct ide_internal *)V3_Malloc(sizeof(struct ide_internal));  
     struct vm_device * device = v3_create_device("IDE", &dev_ops, ide);
 
     ide->pci = pci;
+    ide->southbridge = southbridge;
 
     PrintDebug("IDE: Creating IDE bus x 2\n");
 
index 14ad96b..102024c 100644 (file)
@@ -355,14 +355,14 @@ static inline int is_cfg_reg_writable(uchar_t header_type, int reg_num) {
 static int bar_update(struct pci_device * pci, int bar_num, uint32_t new_val) {
     struct v3_pci_bar * bar = &(pci->bar[bar_num]);
 
-    PrintError("Updating BAR Register  (Dev=%s) (bar=%d) (old_val=%x) (new_val=%x)\n", 
+    PrintDebug("Updating BAR Register  (Dev=%s) (bar=%d) (old_val=%x) (new_val=%x)\n", 
               pci->name, bar_num, bar->val, new_val);
 
     switch (bar->type) {
        case PCI_BAR_IO: {
            int i = 0;
 
-               PrintError("\tRehooking %d IO ports from base %x to %x\n",
+               PrintDebug("\tRehooking %d IO ports from base %x to %x\n",
                           bar->num_ports, PCI_IO_BASE(bar->val), PCI_IO_BASE(new_val));
                
            // only do this if pci device is enabled....
@@ -379,7 +379,7 @@ static int bar_update(struct pci_device * pci, int bar_num, uint32_t new_val) {
            break;
        }
        case PCI_BAR_NONE: {
-           PrintError("Reprogramming an unsupported BAR register (Dev=%s) (bar=%d) (val=%x)\n", 
+           PrintDebug("Reprogramming an unsupported BAR register (Dev=%s) (bar=%d) (val=%x)\n", 
                       pci->name, bar_num, new_val);
            break;
        }
diff --git a/palacios/src/devices/piix3.c b/palacios/src/devices/piix3.c
new file mode 100644 (file)
index 0000000..60bec64
--- /dev/null
@@ -0,0 +1,68 @@
+/* 
+ * 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".
+ */ 
+#include <devices/piix3.h>
+#include <palacios/vmm.h>
+#include <devices/pci.h>
+
+
+struct piix3_state {
+    uint8_t pci_dev_num;
+
+    struct vm_device * pci;
+
+};
+
+
+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 = NULL,
+    .start = NULL,
+    .stop = NULL,
+};
+
+
+struct vm_device * v3_create_piix3(struct vm_device * pci) {
+    struct piix3_state * piix3 = (struct piix3_state *)V3_Malloc(sizeof(struct piix3_state));
+    struct vm_device * dev = NULL;
+
+    piix3->pci = pci;
+    
+    dev = v3_create_device("PIIX3", &dev_ops, piix3);
+
+    PrintDebug("Created PIIX3\n");
+
+    return dev;
+}
index 3129ec5..60a19f0 100644 (file)
 #include <devices/ide.h>
 
 
+
+#ifndef DEBUG_IDE
+#undef PrintDebug
+#define PrintDebug(fmt, args...)
+#endif
+
 struct hd_state {
     addr_t disk_image;
     uint32_t capacity; // in bytes
index 54e8a3d..7c1abf5 100644 (file)
@@ -63,7 +63,9 @@ int v3_handle_svm_halt(struct guest_info * info)
     
        //v3_update_time(info, yield_stop - yield_start);
        gap = yield_stop - yield_start;
-       v3_raise_irq(info, 0);
+       if (!v3_intr_pending(info)) {
+           v3_raise_irq(info, 0);
+       }
        
        PrintDebug("GeekOS Yield Done (%d cycles)\n", gap);
        
index bddacf2..6d38fb7 100644 (file)
@@ -78,7 +78,7 @@ int v3_handle_svm_exit(struct guest_info * info) {
 #endif
        if (!guest_ctrl->exit_int_info.valid) {
            info->intr_state.irq_pending = 0;
-           // PrintDebug("Injecting Interrupt %d\n", info->intr_state.irq_vector);
+           // PrintDebug("Injected Interrupt %d\n", info->intr_state.irq_vector);
            v3_injecting_intr(info, info->intr_state.irq_vector, EXTERNAL_IRQ);
        } else {
 #ifdef DEBUG_INTERRUPTS
@@ -93,8 +93,6 @@ int v3_handle_svm_exit(struct guest_info * info) {
     // Disable printing io exits due to bochs debug messages
     //if (!((exit_code == VMEXIT_IOIO) && ((ushort_t)(guest_ctrl->exit_info1 >> 16) == 0x402))) {
     
-    
-    //  PrintDebug("SVM Returned: Exit Code: 0x%x \t\t(tsc=%ul)\n",exit_code, (uint_t)info->time_state.guest_tsc); 
   
     if ((0) && (exit_code <= VMEXIT_EXCP14)) {
        uchar_t instr[32];
@@ -141,7 +139,7 @@ int v3_handle_svm_exit(struct guest_info * info) {
     switch (exit_code) {
        case VMEXIT_IOIO: {
            struct svm_io_info * io_info = (struct svm_io_info *)&(guest_ctrl->exit_info1);
-               
+
            if (io_info->type == 0) {
                if (io_info->str) {
 
index 01fcaf7..ff6dce4 100644 (file)
@@ -42,7 +42,8 @@
 #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>
@@ -280,12 +281,15 @@ 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 * ram_cd = NULL;
-    struct vm_device * ram_hd = NULL;
-    struct vm_device * pci = v3_create_pci();
+    struct vm_device * ramdisk = NULL;
+    
+    struct vm_device * pci = NULL;
+    struct vm_device * northbridge = NULL;
+    struct vm_device * southbridge = NULL;
+
     struct vm_device * nvram = v3_create_nvram();
-    //struct vm_device * timer = v3_create_timer();
     struct vm_device * pic = v3_create_pic();
     struct vm_device * keyboard = v3_create_keyboard();
     struct vm_device * pit = v3_create_pit(); 
@@ -295,22 +299,33 @@ static int setup_devices(struct guest_info * info, struct v3_vm_config * config_
     struct vm_device * ioapic = v3_create_io_apic(apic);
     struct vm_device * para_net = v3_create_para_net();
 
+
     //struct vm_device * serial = v3_create_serial();
     struct vm_device * generic = NULL;
 
-    int use_ramdisk = config_ptr->use_ramdisk;
+
     int use_generic = USE_GENERIC;
 
-    ide = v3_create_ide(pci);
+    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);
+    }
+
 
-    if (use_ramdisk) {
-       PrintDebug("Creating Ramdisk\n");
-       //ram_cd = v3_create_ram_cd(ide, 0, 0, 
-       //                (addr_t)(config_ptr->ramdisk), 
-       //                config_ptr->ramdisk_size);
-       ram_hd = v3_create_ram_hd(ide, 0, 0, 
-                                 (addr_t)(config_ptr->ramdisk), 
-                                 config_ptr->ramdisk_size);
+    if (config_ptr->use_ram_cd == 1) {
+       PrintDebug("Creating Ram CD\n");
+       ramdisk = v3_create_ram_cd(ide, 0, 0, 
+                                  (addr_t)(config_ptr->ramdisk), 
+                                  config_ptr->ramdisk_size);
+    } else if (config_ptr->use_ram_hd == 1) {
+       PrintDebug("Creating Ram HD\n");
+       ramdisk = v3_create_ram_hd(ide, 0, 0, 
+                                  (addr_t)(config_ptr->ramdisk), 
+                                  config_ptr->ramdisk_size);
     }
     
     
@@ -319,10 +334,9 @@ static int setup_devices(struct guest_info * info, struct v3_vm_config * config_
     }
 
 
-    v3_attach_device(info, pci);
+
 
     v3_attach_device(info, nvram);
-    //v3_attach_device(info, timer);
     v3_attach_device(info, pic);
     v3_attach_device(info, pit);
     v3_attach_device(info, keyboard);
@@ -335,11 +349,17 @@ static int setup_devices(struct guest_info * info, struct v3_vm_config * config_
 
     v3_attach_device(info, para_net);
 
+    if (config_ptr->enable_pci == 1) {
+       v3_attach_device(info, pci);
+       v3_attach_device(info, northbridge);
+       v3_attach_device(info, southbridge);
+    }
+
     v3_attach_device(info, ide);
 
-    if (use_ramdisk) {
-       //              v3_attach_device(info, ram_cd);
-       v3_attach_device(info, ram_hd);
+
+    if (ramdisk != NULL) {
+       v3_attach_device(info, ramdisk);
     }
 
     if (use_generic) {
@@ -349,28 +369,6 @@ static int setup_devices(struct guest_info * info, struct v3_vm_config * config_
     
     PrintDebugDevMgr(info);
 
-
-    // give keyboard interrupts to vm
-    // no longer needed since we have a keyboard device
-    //hook_irq(&vm_info, 1);
-    
-#if 0
-    // give floppy controller to vm
-    v3_hook_passthrough_irq(info, 6);
-#endif
-    
-    
-    if (!use_ramdisk) {
-       PrintDebug("Hooking IDE IRQs\n");
-       
-       //primary ide
-       v3_hook_passthrough_irq(info, 14);
-       
-       // secondary ide
-       v3_hook_passthrough_irq(info, 15);    
-    }  
-    
-
     return 0;
 }
 
@@ -413,8 +411,8 @@ static struct vm_device *  configure_generic(struct guest_info * info, struct v3
 
     // Make the PCI bus invisible (at least it's configuration)
     
-    v3_generic_add_port_range(generic, 0xcf8, 0xcf8, GENERIC_PRINT_AND_IGNORE); // PCI Config Address
-    v3_generic_add_port_range(generic, 0xcfc, 0xcfc, GENERIC_PRINT_AND_IGNORE); // PCI Config Data
+    //v3_generic_add_port_range(generic, 0xcf8, 0xcf8, GENERIC_PRINT_AND_IGNORE); // PCI Config Address
+    //v3_generic_add_port_range(generic, 0xcfc, 0xcfc, GENERIC_PRINT_AND_IGNORE); // PCI Config Data