From: Jack Lange Date: Wed, 8 Apr 2009 00:22:01 +0000 (-0500) Subject: updated the pci and IDE configuration. X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=a7dc3322984b3c76fe990de506418e180ec1b0de updated the pci and IDE configuration. Made the IDE/PCI system configurable via the config struct. Starting to add the north/south bridges as virtual devices DMA still not working.... --- diff --git a/palacios/build/Makefile b/palacios/build/Makefile index 46fcc40..4e8c8e3 100644 --- a/palacios/build/Makefile +++ b/palacios/build/Makefile @@ -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 index 0000000..db390a8 --- /dev/null +++ b/palacios/include/devices/piix3.h @@ -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 + * Copyright (c) 2009, Chang Seok Bae + * Copyright (c) 2009, Jack Lange + * Copyright (c) 2009, The V3VEE Project + * All rights reserved. + * + * Author: Lei Xia + * Chang Seok Bae + * Jack Lange + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + +#ifndef __DEVICES_PIIX3_H__ +#define __DEVICES_PIIX3_H__ + + +#ifdef __V3VEE__ + +#include + + +struct vm_device * v3_create_piix3(struct vm_device * pci); + +#endif // ! __V3VEE__ + +#endif diff --git a/palacios/include/palacios/vmm.h b/palacios/include/palacios/vmm.h index 4a4ed79..f5bad18 100644 --- a/palacios/include/palacios/vmm.h +++ b/palacios/include/palacios/vmm.h @@ -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; }; diff --git a/palacios/src/devices/ata.h b/palacios/src/devices/ata.h index 1e8df43..e31377a 100644 --- a/palacios/src/devices/ata.h +++ b/palacios/src/devices/ata.h @@ -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 + } diff --git a/palacios/src/devices/ide.c b/palacios/src/devices/ide.c index bf85ba1..562688f 100644 --- a/palacios/src/devices/ide.c +++ b/palacios/src/devices/ide.c @@ -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"); diff --git a/palacios/src/devices/pci.c b/palacios/src/devices/pci.c index 14ad96b..102024c 100644 --- a/palacios/src/devices/pci.c +++ b/palacios/src/devices/pci.c @@ -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 index 0000000..60bec64 --- /dev/null +++ b/palacios/src/devices/piix3.c @@ -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 + * Copyright (c) 2009, Chang Seok Bae + * Copyright (c) 2009, Jack Lange + * Copyright (c) 2009, The V3VEE Project + * All rights reserved. + * + * Author: Lei Xia + * Chang Seok Bae + * Jack Lange + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + +#include +#include +#include + + +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; +} diff --git a/palacios/src/devices/ram_hd.c b/palacios/src/devices/ram_hd.c index 3129ec5..60a19f0 100644 --- a/palacios/src/devices/ram_hd.c +++ b/palacios/src/devices/ram_hd.c @@ -22,6 +22,12 @@ #include + +#ifndef DEBUG_IDE +#undef PrintDebug +#define PrintDebug(fmt, args...) +#endif + struct hd_state { addr_t disk_image; uint32_t capacity; // in bytes diff --git a/palacios/src/palacios/svm_halt.c b/palacios/src/palacios/svm_halt.c index 54e8a3d..7c1abf5 100644 --- a/palacios/src/palacios/svm_halt.c +++ b/palacios/src/palacios/svm_halt.c @@ -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); diff --git a/palacios/src/palacios/svm_handler.c b/palacios/src/palacios/svm_handler.c index bddacf2..6d38fb7 100644 --- a/palacios/src/palacios/svm_handler.c +++ b/palacios/src/palacios/svm_handler.c @@ -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) { diff --git a/palacios/src/palacios/vmm_config.c b/palacios/src/palacios/vmm_config.c index 01fcaf7..ff6dce4 100644 --- a/palacios/src/palacios/vmm_config.c +++ b/palacios/src/palacios/vmm_config.c @@ -42,7 +42,8 @@ #include #include #include - +#include +#include #include @@ -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