From: Jack Lange Date: Wed, 8 Apr 2009 05:20:21 +0000 (-0500) Subject: updates to the PCI configuration for the southbridge and northbridge X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=a0e1d8274aef54adcf50dce0b3843489f2a3cd21 updates to the PCI configuration for the southbridge and northbridge --- diff --git a/palacios/include/devices/pci.h b/palacios/include/devices/pci.h index 6727e44..66841a8 100644 --- a/palacios/include/devices/pci.h +++ b/palacios/include/devices/pci.h @@ -67,6 +67,7 @@ struct v3_pci_bar { #define PCI_MEM32_BASE(bar_val) (bar_val & 0xfffffff0) struct pci_device { + union { uint8_t config_space[256]; @@ -76,14 +77,20 @@ struct pci_device { } __attribute__((packed)); } __attribute__((packed)); - - struct v3_pci_bar bar[6]; - uint_t bus_num; struct rb_node dev_tree_node; - int dev_num; + uint_t bus_num; + + union { + uint8_t devfn; + struct { + uint8_t fn_num : 3; + uint8_t dev_num : 5; + } __attribute__((packed)); + } __attribute__((packed)); + char name[64]; struct vm_device * vm_dev; //the corresponding virtual device @@ -93,7 +100,6 @@ struct pci_device { int (*cmd_update)(struct pci_device *pci_dev, uchar_t io_enabled, uchar_t mem_enabled); int (*ext_rom_update)(struct pci_device *pci_dev); - int ext_rom_update_flag; int bar_update_flag; @@ -107,9 +113,10 @@ struct vm_device * v3_create_pci(); struct pci_device * v3_pci_register_device(struct vm_device * pci, pci_device_type_t dev_type, - uint_t bus_num, - const char * name, + int bus_num, int dev_num, + int fn_num, + const char * name, struct v3_pci_bar * bars, int (*config_update)(struct pci_device * pci_dev, uint_t reg_num, int length), int (*cmd_update)(struct pci_device *pci_dev, uchar_t io_enabled, uchar_t mem_enabled), diff --git a/palacios/include/devices/southbridge.h b/palacios/include/devices/southbridge.h new file mode 100644 index 0000000..966d652 --- /dev/null +++ b/palacios/include/devices/southbridge.h @@ -0,0 +1,41 @@ +/* + * 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, The V3VEE Project + * All rights reserved. + * + * Author: Lei Xia + * Chang Seok Bae + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + +#ifndef __DEVICES_SOUTHBRIDGE_H__ +#define __DEVICES_SOUTHBRIDGE_H__ + + +#ifdef __V3VEE__ + + +typedef enum {V3_SB_INVALID, V3_SB_PIIX3, V3_SB_PIIX4, V3_SB_CMD646} v3_southbridge_type_t; + +struct v3_southbridge { + struct vm_device * pci_bus; + struct pci_device * southbridge_pci; + + v3_southbridge_type_t type; +}; + + +#endif // ! __V3VEE__ + +#endif diff --git a/palacios/src/devices/i440fx.c b/palacios/src/devices/i440fx.c index 9d712df..793dc28 100644 --- a/palacios/src/devices/i440fx.c +++ b/palacios/src/devices/i440fx.c @@ -19,9 +19,10 @@ #include #include +#include struct i440_state { - int foo; + struct vm_device * pci; }; @@ -36,25 +37,38 @@ static int io_write(ushort_t port, void * src, uint_t length, struct vm_device * } -static int i440_init(struct vm_device * dev) { - // struct i440_state * state = (struct i440_state *)(dev->private_data); - - - v3_dev_hook_io(dev, 0x00b2, - &io_read, &io_write); - v3_dev_hook_io(dev, 0x00b3, - &io_read, &io_write); +static int i440_init(struct vm_device * dev) { + struct i440_state * state = (struct i440_state *)(dev->private_data); + struct pci_device * pci_dev = NULL; + struct v3_pci_bar bars[6]; + int i; - v3_dev_hook_io(dev, 0x0cf8, - &io_read, &io_write); + for (i = 0; i < 4; i++) { + v3_dev_hook_io(dev, 0x0cf8 + i, + &io_read, &io_write); + v3_dev_hook_io(dev, 0x0cfc + i, + &io_read, &io_write); + } + for (i = 0; i < 6; i++) { + bars[i].type = PCI_BAR_NONE; + } + pci_dev = v3_pci_register_device(state->pci, PCI_STD_DEVICE, 0, 0, 0, "i440FX", bars, + NULL, NULL, NULL, dev); - v3_dev_hook_io(dev, 0x0cf9, - &io_read, &io_write); + if (!pci_dev) { + return -1; + } + pci_dev->config_header.vendor_id = 0x8086; + pci_dev->config_header.device_id = 0x1237; + pci_dev->config_header.revision = 0x0002; + pci_dev->config_header.subclass = 0x00; // SubClass: host2pci + pci_dev->config_header.class = 0x06; // Class: PCI bridge + pci_dev->config_space[0x72] = 0x02; // SMRAM (?) return 0; } @@ -75,14 +89,13 @@ static struct vm_device_ops dev_ops = { 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; - } diff --git a/palacios/src/devices/ide.c b/palacios/src/devices/ide.c index 562688f..505f5cf 100644 --- a/palacios/src/devices/ide.c +++ b/palacios/src/devices/ide.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "ide-types.h" #include "atapi-types.h" @@ -208,8 +209,6 @@ struct ide_channel { int irq; // this is temporary until we add PCI support - struct pci_device * pci_dev; - // Control Registers struct ide_ctrl_reg ctrl_reg; // [write] 0x3f6,0x376 @@ -223,9 +222,11 @@ struct ide_channel { struct ide_internal { struct ide_channel channels[2]; - struct vm_device * pci; - struct vm_device * southbridge; - struct pci_device * busmaster_pci; + + struct v3_southbridge * southbridge; + struct vm_device * pci_bus; + + struct pci_device * ide_pci; }; @@ -421,39 +422,6 @@ static int dma_write(struct vm_device * dev, struct ide_channel * channel) { } -/* - * This is an ugly ugly ugly way to differentiate between the first and second DMA channels - */ - -static int write_dma_port(ushort_t port_offset, void * src, uint_t length, struct vm_device * dev, struct ide_channel * channel); -static int read_dma_port(ushort_t port_offset, void * dst, uint_t length, struct vm_device * dev, struct ide_channel * channel); - - -static int write_pri_dma_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) { - struct ide_internal * ide = (struct ide_internal *)(dev->private_data); - PrintDebug("IDE: Writing PRI DMA Port %x (%s) (val=%x)\n", port, dma_port_to_str(port & 0x7), *(uint32_t *)src); - return write_dma_port(port & 0x7, src, length, dev, &(ide->channels[0])); -} - -static int write_sec_dma_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) { - struct ide_internal * ide = (struct ide_internal *)(dev->private_data); - PrintDebug("IDE: Writing SEC DMA Port %x (%s) (val=%x)\n", port, dma_port_to_str(port & 0x7), *(uint32_t *)src); - return write_dma_port(port & 0x7, src, length, dev, &(ide->channels[1])); -} - - -static int read_pri_dma_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) { - struct ide_internal * ide = (struct ide_internal *)(dev->private_data); - PrintDebug("IDE: Reading PRI DMA Port %x (%s)\n", port, dma_port_to_str(port & 0x7)); - return read_dma_port(port & 0x7, dst, length, dev, &(ide->channels[0])); -} - -static int read_sec_dma_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) { - struct ide_internal * ide = (struct ide_internal *)(dev->private_data); - PrintDebug("IDE: Reading SEC DMA Port %x (%s)\n", port, dma_port_to_str(port & 0x7)); - return read_dma_port(port & 0x7, dst, length, dev, &(ide->channels[1])); -} - #define DMA_CMD_PORT 0x00 #define DMA_STATUS_PORT 0x02 @@ -462,9 +430,13 @@ static int read_sec_dma_port(ushort_t port, void * dst, uint_t length, struct vm #define DMA_PRD_PORT2 0x06 #define DMA_PRD_PORT3 0x07 +#define DMA_CHANNEL_FLAG 0x08 -static int write_dma_port(ushort_t port_offset, void * src, uint_t length, - struct vm_device * dev, struct ide_channel * channel) { +static int write_dma_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) { + struct ide_internal * ide = (struct ide_internal *)(dev->private_data); + uint16_t port_offset = port & (DMA_CHANNEL_FLAG - 1); + uint_t channel_flag = (port & DMA_CHANNEL_FLAG) >> 3; + struct ide_channel * channel = &(ide->channels[channel_flag]); switch (port_offset) { case DMA_CMD_PORT: @@ -533,8 +505,11 @@ static int write_dma_port(ushort_t port_offset, void * src, uint_t length, } -static int read_dma_port(ushort_t port_offset, void * dst, uint_t length, - struct vm_device * dev, struct ide_channel * channel) { +static int read_dma_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) { + struct ide_internal * ide = (struct ide_internal *)(dev->private_data); + uint16_t port_offset = port & (DMA_CHANNEL_FLAG - 1); + uint_t channel_flag = (port & DMA_CHANNEL_FLAG) >> 3; + struct ide_channel * channel = &(ide->channels[channel_flag]); switch (port_offset) { case DMA_CMD_PORT: @@ -1165,80 +1140,27 @@ 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); - int i, j; - + int i; /* - Check if the PIIX 3 actually represents both IDE channels in a single PCI entry */ + * 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; - - - if (ide->pci) { - struct v3_pci_bar bars[6]; - struct pci_device * pci_dev = NULL; - - for (j = 0; j < 6; j++) { - bars[j].type = PCI_BAR_NONE; - } - - - 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); - - 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; - } - - } + return 0; } static int init_ide(struct vm_device * dev) { - //struct ide_internal * ide = (struct ide_internal *)(dev->private_data); + struct ide_internal * ide = (struct ide_internal *)(dev->private_data); PrintDebug("IDE: Initializing IDE\n"); @@ -1296,6 +1218,53 @@ static int init_ide(struct vm_device * dev) { v3_dev_hook_io(dev, PRI_ADDR_REG_PORT, &read_port_std, &write_port_std); + + + + if (ide->pci_bus) { + struct v3_pci_bar bars[6]; + struct v3_southbridge * southbridge = (struct v3_southbridge *)(ide->southbridge); + struct pci_device * sb_pci = (struct pci_device *)(southbridge->southbridge_pci); + struct pci_device * pci_dev = NULL; + int i; + + for (i = 0; i < 6; i++) { + bars[i].type = PCI_BAR_NONE; + } + + bars[4].type = PCI_BAR_IO; + bars[4].default_base_port = PRI_DEFAULT_DMA_PORT; + bars[4].num_ports = 16; + + bars[4].io_read = read_dma_port; + bars[4].io_write = write_dma_port; + + pci_dev = v3_pci_register_device(ide->pci_bus, PCI_STD_DEVICE, 0, sb_pci->dev_num, 1, + "PIIX3_IDE", bars, + pci_config_update, NULL, NULL, dev); + + if (pci_dev == NULL) { + PrintError("Failed to register IDE BUS %d with PCI\n", i); + return -1; + } + + /* 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; + } + return 0; } @@ -1316,12 +1285,12 @@ static struct vm_device_ops dev_ops = { }; -struct vm_device * v3_create_ide(struct vm_device * pci, struct vm_device * southbridge) { +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)); struct vm_device * device = v3_create_device("IDE", &dev_ops, ide); - ide->pci = pci; - ide->southbridge = southbridge; + ide->pci_bus = pci_bus; + ide->southbridge = (struct v3_southbridge *)(southbridge_dev->private_data); PrintDebug("IDE: Creating IDE bus x 2\n"); diff --git a/palacios/src/devices/pci.c b/palacios/src/devices/pci.c index 102024c..6b5472d 100644 --- a/palacios/src/devices/pci.c +++ b/palacios/src/devices/pci.c @@ -154,9 +154,9 @@ struct pci_device * __add_device_to_bus(struct pci_bus * bus, struct pci_device parent = *p; tmp_dev = rb_entry(parent, struct pci_device, dev_tree_node); - if (dev->dev_num < tmp_dev->dev_num) { + if (dev->devfn < tmp_dev->devfn) { p = &(*p)->rb_left; - } else if (dev->dev_num > tmp_dev->dev_num) { + } else if (dev->devfn > tmp_dev->devfn) { p = &(*p)->rb_right; } else { return tmp_dev; @@ -186,16 +186,17 @@ struct pci_device * add_device_to_bus(struct pci_bus * bus, struct pci_device * } -static struct pci_device * get_device(struct pci_bus * bus, int dev_num) { +static struct pci_device * get_device(struct pci_bus * bus, uint8_t dev_num, uint8_t fn_num) { struct rb_node * n = bus->devices.rb_node; struct pci_device * dev = NULL; + uint8_t devfn = ((dev_num & 0x1f) << 3) | (fn_num & 0x7); while (n) { dev = rb_entry(n, struct pci_device, dev_tree_node); - if (dev_num < dev->dev_num) { + if (devfn < dev->devfn) { n = n->rb_left; - } else if (dev_num > dev->dev_num) { + } else if (devfn > dev->devfn) { n = n->rb_right; } else { return dev; @@ -301,7 +302,7 @@ static int data_port_read(ushort_t port, void * dst, uint_t length, struct vm_de reg_num, reg_num, pci_state->addr_reg.val); - pci_dev = get_device(&(pci_state->bus_list[0]), pci_state->addr_reg.dev_num); + pci_dev = get_device(&(pci_state->bus_list[0]), pci_state->addr_reg.dev_num, pci_state->addr_reg.fn_num); if (pci_dev == NULL) { for (i = 0; i < length; i++) { @@ -340,6 +341,24 @@ static inline int is_cfg_reg_writable(uchar_t header_type, int reg_num) { return 1; } + } else if (header_type == 0x80) { + switch (reg_num) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + case 0x0e: + case 0x3d: + return 0; + + default: + return 1; + + } } else { // PCI to PCI Bridge = 0x01 // CardBus Bridge = 0x02 @@ -411,7 +430,7 @@ static int data_port_write(ushort_t port, void * src, uint_t length, struct vm_d *(uint32_t *)src, length); - pci_dev = get_device(&(pci_state->bus_list[0]), pci_state->addr_reg.dev_num); + pci_dev = get_device(&(pci_state->bus_list[0]), pci_state->addr_reg.dev_num, pci_state->addr_reg.fn_num); if (pci_dev == NULL) { PrintError("Writing configuration space for non-present device (dev_num=%d)\n", @@ -422,8 +441,14 @@ static int data_port_write(ushort_t port, void * src, uint_t length, struct vm_d for (i = 0; i < length; i++) { uint_t cur_reg = reg_num + i; + int writable = is_cfg_reg_writable(pci_dev->config_header.header_type, cur_reg); + + if (writable == -1) { + PrintError("Invalid PCI configuration space\n"); + return -1; + } - if (is_cfg_reg_writable(pci_dev->config_header.header_type, cur_reg)) { + if (writable) { pci_dev->config_space[cur_reg] = *(uint8_t *)((uint8_t *)src + i); if ((cur_reg >= 0x10) && (cur_reg < 0x28)) { @@ -528,36 +553,6 @@ static int pci_deinit_device(struct vm_device * dev) { - -static int init_i440fx(struct vm_device * dev) { - struct pci_device * pci_dev = NULL; - struct v3_pci_bar bars[6]; - int i; - - for (i = 0; i < 6; i++) { - bars[i].type = PCI_BAR_NONE; - } - - pci_dev = v3_pci_register_device(dev, PCI_STD_DEVICE, 0, "i440FX", 0, bars, - NULL, NULL, NULL, NULL); - - if (!pci_dev) { - return -1; - } - - pci_dev->config_header.vendor_id = 0x8086; - pci_dev->config_header.device_id = 0x1237; - pci_dev->config_header.revision = 0x0002; - pci_dev->config_header.subclass = 0x00; // SubClass: host2pci - pci_dev->config_header.class = 0x06; // Class: PCI bridge - - pci_dev->bus_num = 0; - return 0; -} - - - - static void init_pci_busses(struct pci_internal * pci_state) { int i; @@ -582,11 +577,6 @@ static int pci_init_device(struct vm_device * dev) { pci_state->addr_reg.val = 0; init_pci_busses(pci_state); - - if (init_i440fx(dev) == -1) { - PrintError("Could not intialize i440fx\n"); - return -1; - } PrintDebug("Sizeof config header=%d\n", (int)sizeof(struct pci_config_header)); @@ -693,9 +683,10 @@ static inline int init_bars(struct pci_device * pci_dev) { // if dev_num == -1, auto assign struct pci_device * v3_pci_register_device(struct vm_device * pci, pci_device_type_t dev_type, - uint_t bus_num, - const char * name, + int bus_num, int dev_num, + int fn_num, + const char * name, struct v3_pci_bar * bars, int (*config_update)(struct pci_device * pci_dev, uint_t reg_num, int length), int (*cmd_update)(struct pci_device *pci_dev, uchar_t io_enabled, uchar_t mem_enabled), @@ -719,7 +710,7 @@ struct pci_device * v3_pci_register_device(struct vm_device * pci, } } - if (get_device(bus, dev_num) != NULL) { + if (get_device(bus, dev_num, fn_num) != NULL) { PrintError("PCI Device already registered at slot %d on bus %d\n", dev_num, bus->bus_num); return NULL; @@ -729,16 +720,20 @@ struct pci_device * v3_pci_register_device(struct vm_device * pci, pci_dev = (struct pci_device *)V3_Malloc(sizeof(struct pci_device)); if (pci_dev == NULL) { + PrintError("Could not allocate pci device\n"); return NULL; } memset(pci_dev, 0, sizeof(struct pci_device)); - + switch (dev_type) { case PCI_STD_DEVICE: pci_dev->config_header.header_type = 0x00; break; + case PCI_MULTIFUNCTION: + pci_dev->config_header.header_type = 0x80; + break; default: PrintError("Unhandled PCI Device Type: %d\n", dev_type); return NULL; @@ -746,6 +741,7 @@ struct pci_device * v3_pci_register_device(struct vm_device * pci, pci_dev->bus_num = bus_num; pci_dev->dev_num = dev_num; + pci_dev->fn_num = fn_num; strncpy(pci_dev->name, name, sizeof(pci_dev->name)); pci_dev->vm_dev = dev; @@ -756,9 +752,8 @@ struct pci_device * v3_pci_register_device(struct vm_device * pci, pci_dev->ext_rom_update = ext_rom_update; - //copy bars - for (i = 0; i < 6; i ++){ + for (i = 0; i < 6; i ++) { pci_dev->bar[i].type = bars[i].type; if (pci_dev->bar[i].type == PCI_BAR_IO) { diff --git a/palacios/src/devices/piix3.c b/palacios/src/devices/piix3.c index 60bec64..7beb6dd 100644 --- a/palacios/src/devices/piix3.c +++ b/palacios/src/devices/piix3.c @@ -24,17 +24,73 @@ #include #include #include +#include + + + +static int reset_piix3(struct vm_device * dev) { + struct v3_southbridge * piix3 = (struct v3_southbridge *)(dev->private_data); + struct pci_device * pci_dev = piix3->southbridge_pci; + + pci_dev->config_header.command = 0x0007; // master, memory and I/O + pci_dev->config_header.status = 0x0200; + + pci_dev->config_space[0x4c] = 0x4d; + pci_dev->config_space[0x4e] = 0x03; + pci_dev->config_space[0x4f] = 0x00; + pci_dev->config_space[0x60] = 0x80; + pci_dev->config_space[0x69] = 0x02; + pci_dev->config_space[0x70] = 0x80; + pci_dev->config_space[0x76] = 0x0c; + pci_dev->config_space[0x77] = 0x0c; + pci_dev->config_space[0x78] = 0x02; + pci_dev->config_space[0x79] = 0x00; + pci_dev->config_space[0x80] = 0x00; + pci_dev->config_space[0x82] = 0x00; + pci_dev->config_space[0xa0] = 0x08; + pci_dev->config_space[0xa2] = 0x00; + pci_dev->config_space[0xa3] = 0x00; + pci_dev->config_space[0xa4] = 0x00; + pci_dev->config_space[0xa5] = 0x00; + pci_dev->config_space[0xa6] = 0x00; + pci_dev->config_space[0xa7] = 0x00; + pci_dev->config_space[0xa8] = 0x0f; + pci_dev->config_space[0xaa] = 0x00; + pci_dev->config_space[0xab] = 0x00; + pci_dev->config_space[0xac] = 0x00; + pci_dev->config_space[0xae] = 0x00; + return 0; +} -struct piix3_state { - uint8_t pci_dev_num; - struct vm_device * pci; +static int init_piix3(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]; + int i; -}; + for (i = 0; i < 6; i++) { + bars[i].type = PCI_BAR_NONE; + } + pci_dev = v3_pci_register_device(piix3->pci_bus, PCI_MULTIFUNCTION, + 0, -1, 0, + "PIIX3", bars, + NULL, NULL, NULL, dev); + if (!pci_dev) { + PrintError("Could not register PCI Device for PIIX3\n"); + return -1; + } -static int init_piix3(struct vm_device * dev) { + pci_dev->config_header.vendor_id = 0x8086; + pci_dev->config_header.device_id = 0x7000; // PIIX4 is 0x7001 + pci_dev->config_header.subclass = 0x01; // SubClass: host2pci + pci_dev->config_header.class = 0x06; // Class: PCI bridge + + piix3->southbridge_pci = pci_dev; + + reset_piix3(dev); return 0; } @@ -48,17 +104,18 @@ static int deinit_piix3(struct vm_device * dev) { static struct vm_device_ops dev_ops = { .init = init_piix3, .deinit = deinit_piix3, - .reset = NULL, + .reset = reset_piix3, .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 v3_southbridge * piix3 = (struct v3_southbridge *)V3_Malloc(sizeof(struct v3_southbridge)); struct vm_device * dev = NULL; - piix3->pci = pci; + piix3->pci_bus = pci; + piix3->type = V3_SB_PIIX3; dev = v3_create_device("PIIX3", &dev_ops, piix3); diff --git a/palacios/src/palacios/vmm_config.c b/palacios/src/palacios/vmm_config.c index ff6dce4..1236a0b 100644 --- a/palacios/src/palacios/vmm_config.c +++ b/palacios/src/palacios/vmm_config.c @@ -350,11 +350,15 @@ 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) { + 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);