提交 ea3fdd5d 编写于 作者: A Anthony Liguori

Merge remote branch 'mst/for_anthony' into staging

......@@ -75,7 +75,7 @@ Main loop Fabrice Bellard (new maintainer needed)
TCG Fabrice Bellard
IDE device ?
SCSI device Paul Brook
PCI layer ?
PCI layer Michael S. Tsirkin
USB layer ?
Block layer ?
Graphic layer ?
......
......@@ -1284,37 +1284,42 @@ static int ac97_initfn (PCIDevice *dev)
pci_config_set_vendor_id (c, PCI_VENDOR_ID_INTEL); /* ro */
pci_config_set_device_id (c, PCI_DEVICE_ID_INTEL_82801AA_5); /* ro */
c[0x04] = 0x00; /* pcicmd pci command rw, ro */
c[0x05] = 0x00;
/* TODO: no need to override */
c[PCI_COMMAND] = 0x00; /* pcicmd pci command rw, ro */
c[PCI_COMMAND + 1] = 0x00;
c[0x06] = 0x80; /* pcists pci status rwc, ro */
c[0x07] = 0x02;
/* TODO: */
c[PCI_STATUS] = PCI_STATUS_FAST_BACK; /* pcists pci status rwc, ro */
c[PCI_STATUS + 1] = PCI_STATUS_DEVSEL_MEDIUM >> 8;
c[0x08] = 0x01; /* rid revision ro */
c[0x09] = 0x00; /* pi programming interface ro */
c[PCI_REVISION_ID] = 0x01; /* rid revision ro */
c[PCI_CLASS_PROG] = 0x00; /* pi programming interface ro */
pci_config_set_class (c, PCI_CLASS_MULTIMEDIA_AUDIO); /* ro */
c[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; /* headtyp header type ro */
c[0x10] = 0x01; /* nabmar native audio mixer base
address rw */
c[0x11] = 0x00;
c[0x12] = 0x00;
c[0x13] = 0x00;
c[0x14] = 0x01; /* nabmbar native audio bus mastering
base address rw */
c[0x15] = 0x00;
c[0x16] = 0x00;
c[0x17] = 0x00;
c[0x2c] = 0x86; /* svid subsystem vendor id rwo */
c[0x2d] = 0x80;
c[0x2e] = 0x00; /* sid subsystem id rwo */
c[0x2f] = 0x00;
c[0x3c] = 0x00; /* intr_ln interrupt line rw */
c[0x3d] = 0x01; /* intr_pn interrupt pin ro */
/* TODO set when bar is registered. no need to override. */
/* nabmar native audio mixer base address rw */
c[PCI_BASE_ADDRESS_0] = PCI_BASE_ADDRESS_SPACE_IO;
c[PCI_BASE_ADDRESS_0 + 1] = 0x00;
c[PCI_BASE_ADDRESS_0 + 2] = 0x00;
c[PCI_BASE_ADDRESS_0 + 3] = 0x00;
/* TODO set when bar is registered. no need to override. */
/* nabmbar native audio bus mastering base address rw */
c[PCI_BASE_ADDRESS_0 + 4] = PCI_BASE_ADDRESS_SPACE_IO;
c[PCI_BASE_ADDRESS_0 + 5] = 0x00;
c[PCI_BASE_ADDRESS_0 + 6] = 0x00;
c[PCI_BASE_ADDRESS_0 + 7] = 0x00;
c[PCI_SUBSYSTEM_VENDOR_ID] = 0x86; /* svid subsystem vendor id rwo */
c[PCI_SUBSYSTEM_VENDOR_ID + 1] = 0x80;
c[PCI_SUBSYSTEM_ID] = 0x00; /* sid subsystem id rwo */
c[PCI_SUBSYSTEM_ID + 1] = 0x00;
c[PCI_INTERRUPT_LINE] = 0x00; /* intr_ln interrupt line rw */
/* TODO: RST# value should be 0. */
c[PCI_INTERRUPT_PIN] = 0x01; /* intr_pn interrupt pin ro */
pci_register_bar (&s->dev, 0, 256 * 4, PCI_BASE_ADDRESS_SPACE_IO,
ac97_map);
......
......@@ -437,7 +437,7 @@ static void pm_write_config(PCIDevice *d,
uint32_t address, uint32_t val, int len)
{
pci_default_write_config(d, address, val, len);
if (address == 0x80)
if (range_covers_byte(address, len, 0x80))
pm_io_space_update((PIIX4PMState *)d);
}
......
......@@ -1092,12 +1092,15 @@ static int pci_e1000_init(PCIDevice *pci_dev)
pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
pci_config_set_device_id(pci_conf, E1000_DEVID);
*(uint16_t *)(pci_conf+0x06) = cpu_to_le16(0x0010);
pci_conf[0x08] = 0x03;
/* TODO: we have no capabilities, so why is this bit set? */
pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_CAP_LIST);
pci_conf[PCI_REVISION_ID] = 0x03;
pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
pci_conf[0x0c] = 0x10;
/* TODO: RST# value should be 0, PCI spec 6.2.4 */
pci_conf[PCI_CACHE_LINE_SIZE] = 0x10;
pci_conf[0x3d] = 1; // interrupt pin 0
/* TODO: RST# value should be 0 if programmable, PCI spec 6.2.4 */
pci_conf[PCI_INTERRUPT_PIN] = 1; // interrupt pin 0
d->mmio_index = cpu_register_io_memory(e1000_mmio_read,
e1000_mmio_write, d);
......
......@@ -412,19 +412,24 @@ static void pci_reset(EEPRO100State * s)
pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
/* PCI Device ID depends on device and is set below. */
/* PCI Command */
/* TODO: this is the default, do not override. */
PCI_CONFIG_16(PCI_COMMAND, 0x0000);
/* PCI Status */
PCI_CONFIG_16(PCI_STATUS, 0x2800);
/* TODO: this seems to make no sense. */
/* TODO: Value at RST# should be 0. */
PCI_CONFIG_16(PCI_STATUS,
PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_SIG_TARGET_ABORT);
/* PCI Revision ID */
PCI_CONFIG_8(PCI_REVISION_ID, 0x08);
/* TODO: this is the default, do not override. */
/* PCI Class Code */
PCI_CONFIG_8(0x09, 0x00);
PCI_CONFIG_8(PCI_CLASS_PROG, 0x00);
pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
/* PCI Cache Line Size */
/* check cache line size!!! */
//~ PCI_CONFIG_8(0x0c, 0x00);
/* PCI Latency Timer */
PCI_CONFIG_8(0x0d, 0x20); // latency timer = 32 clocks
PCI_CONFIG_8(PCI_LATENCY_TIMER, 0x20); // latency timer = 32 clocks
/* PCI Header Type */
/* BIST (built-in self test) */
#if defined(TARGET_I386)
......@@ -446,16 +451,20 @@ static void pci_reset(EEPRO100State * s)
#endif
#endif
/* Expansion ROM Base Address (depends on boot disable!!!) */
PCI_CONFIG_32(0x30, 0x00000000);
/* TODO: not needed, set when BAR is registered */
PCI_CONFIG_32(PCI_ROM_ADDRESS, PCI_BASE_ADDRESS_SPACE_MEMORY);
/* Capability Pointer */
PCI_CONFIG_8(0x34, 0xdc);
/* TODO: revisions with power_management 1 use this but
* do not set new capability list bit in status register. */
PCI_CONFIG_8(PCI_CAPABILITY_LIST, 0xdc);
/* Interrupt Line */
/* Interrupt Pin */
PCI_CONFIG_8(0x3d, 1); // interrupt pin 0
/* TODO: RST# value should be 0 */
PCI_CONFIG_8(PCI_INTERRUPT_PIN, 1); // interrupt pin 0
/* Minimum Grant */
PCI_CONFIG_8(0x3e, 0x08);
PCI_CONFIG_8(PCI_MIN_GNT, 0x08);
/* Maximum Latency */
PCI_CONFIG_8(0x3f, 0x18);
PCI_CONFIG_8(PCI_MAX_LAT, 0x18);
switch (device) {
case i82550:
......@@ -479,52 +488,57 @@ static void pci_reset(EEPRO100State * s)
case i82557A:
pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
PCI_CONFIG_8(PCI_REVISION_ID, 0x01);
PCI_CONFIG_8(0x34, 0x00);
PCI_CONFIG_8(PCI_CAPABILITY_LIST, 0x00);
power_management = 0;
break;
case i82557B:
pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
PCI_CONFIG_8(PCI_REVISION_ID, 0x02);
PCI_CONFIG_8(0x34, 0x00);
PCI_CONFIG_8(PCI_CAPABILITY_LIST, 0x00);
power_management = 0;
break;
case i82557C:
pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
PCI_CONFIG_8(PCI_REVISION_ID, 0x03);
PCI_CONFIG_8(0x34, 0x00);
PCI_CONFIG_8(PCI_CAPABILITY_LIST, 0x00);
power_management = 0;
break;
case i82558A:
pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
PCI_CONFIG_16(PCI_STATUS, 0x0290);
PCI_CONFIG_16(PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM |
PCI_STATUS_FAST_BACK | PCI_STATUS_CAP_LIST);
PCI_CONFIG_8(PCI_REVISION_ID, 0x04);
s->stats_size = 76;
s->has_extended_tcb_support = 1;
break;
case i82558B:
pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
PCI_CONFIG_16(PCI_STATUS, 0x0290);
PCI_CONFIG_16(PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM |
PCI_STATUS_FAST_BACK | PCI_STATUS_CAP_LIST);
PCI_CONFIG_8(PCI_REVISION_ID, 0x05);
s->stats_size = 76;
s->has_extended_tcb_support = 1;
break;
case i82559A:
pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
PCI_CONFIG_16(PCI_STATUS, 0x0290);
PCI_CONFIG_16(PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM |
PCI_STATUS_FAST_BACK | PCI_STATUS_CAP_LIST);
PCI_CONFIG_8(PCI_REVISION_ID, 0x06);
s->stats_size = 80;
s->has_extended_tcb_support = 1;
break;
case i82559B:
pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
PCI_CONFIG_16(PCI_STATUS, 0x0290);
PCI_CONFIG_16(PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM |
PCI_STATUS_FAST_BACK | PCI_STATUS_CAP_LIST);
PCI_CONFIG_8(PCI_REVISION_ID, 0x07);
s->stats_size = 80;
s->has_extended_tcb_support = 1;
break;
case i82559C:
pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
PCI_CONFIG_16(PCI_STATUS, 0x0290);
PCI_CONFIG_16(PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM |
PCI_STATUS_FAST_BACK | PCI_STATUS_CAP_LIST);
PCI_CONFIG_8(PCI_REVISION_ID, 0x08);
// TODO: Windows wants revision id 0x0c.
PCI_CONFIG_8(PCI_REVISION_ID, 0x0c);
......@@ -537,7 +551,8 @@ static void pci_reset(EEPRO100State * s)
break;
case i82559ER:
pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82551IT);
PCI_CONFIG_16(PCI_STATUS, 0x0290);
PCI_CONFIG_16(PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM |
PCI_STATUS_FAST_BACK | PCI_STATUS_CAP_LIST);
PCI_CONFIG_8(PCI_REVISION_ID, 0x09);
s->stats_size = 80;
s->has_extended_tcb_support = 1;
......
......@@ -1000,27 +1000,28 @@ static int es1370_initfn (PCIDevice *dev)
pci_config_set_vendor_id (c, PCI_VENDOR_ID_ENSONIQ);
pci_config_set_device_id (c, PCI_DEVICE_ID_ENSONIQ_ES1370);
c[0x07] = 2 << 1;
c[PCI_STATUS + 1] = PCI_STATUS_DEVSEL_SLOW >> 8;
pci_config_set_class (c, PCI_CLASS_MULTIMEDIA_AUDIO);
#if 1
c[0x2c] = 0x42;
c[0x2d] = 0x49;
c[0x2e] = 0x4c;
c[0x2f] = 0x4c;
c[PCI_SUBSYSTEM_VENDOR_ID] = 0x42;
c[PCI_SUBSYSTEM_VENDOR_ID + 1] = 0x49;
c[PCI_SUBSYSTEM_ID] = 0x4c;
c[PCI_SUBSYSTEM_ID + 1] = 0x4c;
#else
c[0x2c] = 0x74;
c[0x2d] = 0x12;
c[0x2e] = 0x71;
c[0x2f] = 0x13;
c[0x34] = 0xdc;
c[0x3c] = 10;
c[PCI_SUBSYSTEM_VENDOR_ID] = 0x74;
c[PCI_SUBSYSTEM_VENDOR_ID + 1] = 0x12;
c[PCI_SUBSYSTEM_ID] = 0x71;
c[PCI_SUBSYSTEM_ID + 1] = 0x13;
c[PCI_CAPABILITY_LIST] = 0xdc;
c[PCI_INTERRUPT_LINE] = 10;
c[0xdc] = 0x00;
#endif
c[0x3d] = 1;
c[0x3e] = 0x0c;
c[0x3f] = 0x80;
/* TODO: RST# value should be 0. */
c[PCI_INTERRUPT_PIN] = 1;
c[PCI_MIN_GNT] = 0x0c;
c[PCI_MAX_LAT] = 0x80;
pci_register_bar (&s->dev, 0, 256, PCI_BASE_ADDRESS_SPACE_IO, es1370_map);
qemu_register_reset (es1370_on_reset, s);
......
......@@ -1082,17 +1082,6 @@ static void gt64120_reset(void *opaque)
gt64120_pci_mapping(s);
}
static uint32_t gt64120_read_config(PCIDevice *d, uint32_t address, int len)
{
return pci_default_read_config(d, address, len);
}
static void gt64120_write_config(PCIDevice *d, uint32_t address, uint32_t val,
int len)
{
pci_default_write_config(d, address, val, len);
}
static void gt64120_save(QEMUFile* f, void *opaque)
{
PCIDevice *d = opaque;
......@@ -1125,7 +1114,7 @@ PCIBus *pci_gt64120_init(qemu_irq *pic)
pic, 144, 4);
s->ISD_handle = cpu_register_io_memory(gt64120_read, gt64120_write, s);
d = pci_register_device(s->pci->bus, "GT64120 PCI Bus", sizeof(PCIDevice),
0, gt64120_read_config, gt64120_write_config);
0, NULL, NULL);
/* FIXME: Malta specific hw assumptions ahead */
......
......@@ -206,8 +206,8 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev)
pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_CMD);
pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_CMD_646);
pci_conf[0x08] = 0x07; // IDE controller revision
pci_conf[0x09] = 0x8f;
pci_conf[PCI_REVISION_ID] = 0x07; // IDE controller revision
pci_conf[PCI_CLASS_PROG] = 0x8f;
pci_config_set_class(pci_conf, PCI_CLASS_STORAGE_IDE);
pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
......@@ -224,7 +224,8 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev)
pci_register_bar(dev, 3, 0x4, PCI_BASE_ADDRESS_SPACE_IO, ide_map);
pci_register_bar(dev, 4, 0x10, PCI_BASE_ADDRESS_SPACE_IO, bmdma_map);
pci_conf[0x3d] = 0x01; // interrupt on pin 1
/* TODO: RST# value should be 0 */
pci_conf[PCI_INTERRUPT_PIN] = 0x01; // interrupt on pin 1
irq = qemu_allocate_irqs(cmd646_set_irq, d, 2);
ide_bus_new(&d->bus[0], &d->dev.qdev);
......
......@@ -107,10 +107,13 @@ static void piix3_reset(void *opaque)
ide_dma_reset(&d->bmdma[i]);
}
pci_conf[0x04] = 0x00;
pci_conf[0x05] = 0x00;
pci_conf[0x06] = 0x80; /* FBC */
pci_conf[0x07] = 0x02; // PCI_status_devsel_medium
/* TODO: this is the default. do not override. */
pci_conf[PCI_COMMAND] = 0x00;
/* TODO: this is the default. do not override. */
pci_conf[PCI_COMMAND + 1] = 0x00;
/* TODO: use pci_set_word */
pci_conf[PCI_STATUS] = PCI_STATUS_FAST_BACK;
pci_conf[PCI_STATUS + 1] = PCI_STATUS_DEVSEL_MEDIUM >> 8;
pci_conf[0x20] = 0x01; /* BMIBA: 20-23h */
}
......@@ -118,7 +121,7 @@ static int pci_piix_ide_initfn(PCIIDEState *d)
{
uint8_t *pci_conf = d->dev.config;
pci_conf[0x09] = 0x80; // legacy ATA mode
pci_conf[PCI_CLASS_PROG] = 0x80; // legacy ATA mode
pci_config_set_class(pci_conf, PCI_CLASS_STORAGE_IDE);
pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
......
......@@ -2120,18 +2120,20 @@ static int lsi_scsi_init(PCIDevice *dev)
/* PCI base class code */
pci_config_set_class(pci_conf, PCI_CLASS_STORAGE_SCSI);
/* PCI subsystem ID */
pci_conf[0x2e] = 0x00;
pci_conf[0x2f] = 0x10;
pci_conf[PCI_SUBSYSTEM_ID] = 0x00;
pci_conf[PCI_SUBSYSTEM_ID + 1] = 0x10;
/* PCI latency timer = 255 */
pci_conf[0x0d] = 0xff;
pci_conf[PCI_LATENCY_TIMER] = 0xff;
/* TODO: RST# value should be 0 */
/* Interrupt pin 1 */
pci_conf[0x3d] = 0x01;
pci_conf[PCI_INTERRUPT_PIN] = 0x01;
s->mmio_io_addr = cpu_register_io_memory(lsi_mmio_readfn,
lsi_mmio_writefn, s);
s->ram_io_addr = cpu_register_io_memory(lsi_ram_readfn,
lsi_ram_writefn, s);
/* TODO: use dev and get rid of cast below */
pci_register_bar((struct PCIDevice *)s, 0, 256,
PCI_BASE_ADDRESS_SPACE_IO, lsi_io_mapfunc);
pci_register_bar((struct PCIDevice *)s, 1, 0x400,
......
......@@ -175,7 +175,7 @@ void msix_write_config(PCIDevice *dev, uint32_t addr,
unsigned enable_pos = dev->msix_cap + MSIX_CONTROL_OFFSET;
int vector;
if (addr + len <= enable_pos || addr > enable_pos) {
if (!range_covers_byte(addr, len, enable_pos)) {
return;
}
......
......@@ -724,7 +724,8 @@ static int pci_ne2000_init(PCIDevice *pci_dev)
pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_REALTEK_8029);
pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
pci_conf[0x3d] = 1; // interrupt pin 0
/* TODO: RST# value should be 0. PCI spec 6.2.4 */
pci_conf[PCI_INTERRUPT_PIN] = 1; // interrupt pin 0
pci_register_bar(&d->dev, 0, 0x100,
PCI_BASE_ADDRESS_SPACE_IO, ne2000_map);
......
......@@ -41,7 +41,6 @@ struct PCIBus {
pci_set_irq_fn set_irq;
pci_map_irq_fn map_irq;
pci_hotplug_fn hotplug;
uint32_t config_reg; /* XXX: suppress */
void *irq_opaque;
PCIDevice *devices[256];
PCIDevice *parent_dev;
......@@ -420,7 +419,7 @@ static int pci_set_default_subsystem_id(PCIDevice *pci_dev)
{
uint16_t *id;
id = (void*)(&pci_dev->config[PCI_SUBVENDOR_ID]);
id = (void*)(&pci_dev->config[PCI_SUBSYSTEM_VENDOR_ID]);
id[0] = cpu_to_le16(pci_default_sub_vendor_id);
id[1] = cpu_to_le16(pci_default_sub_device_id);
return 0;
......@@ -526,7 +525,8 @@ static void pci_init_wmask(PCIDevice *dev)
dev->wmask[PCI_CACHE_LINE_SIZE] = 0xff;
dev->wmask[PCI_INTERRUPT_LINE] = 0xff;
pci_set_word(dev->wmask + PCI_COMMAND,
PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
PCI_COMMAND_INTX_DISABLE);
memset(dev->wmask + PCI_CONFIG_HEADER_SIZE, 0xff,
config_size - PCI_CONFIG_HEADER_SIZE);
......@@ -959,6 +959,25 @@ static void pci_update_mappings(PCIDevice *d)
}
}
static inline int pci_irq_disabled(PCIDevice *d)
{
return pci_get_word(d->config + PCI_COMMAND) & PCI_COMMAND_INTX_DISABLE;
}
/* Called after interrupt disabled field update in config space,
* assert/deassert interrupts if necessary.
* Gets original interrupt disable bit value (before update). */
static void pci_update_irq_disabled(PCIDevice *d, int was_irq_disabled)
{
int i, disabled = pci_irq_disabled(d);
if (disabled == was_irq_disabled)
return;
for (i = 0; i < PCI_NUM_PINS; ++i) {
int state = pci_irq_state(d, i);
pci_change_irq_level(d, i, disabled ? -state : state);
}
}
uint32_t pci_default_read_config(PCIDevice *d,
uint32_t address, int len)
{
......@@ -971,7 +990,7 @@ uint32_t pci_default_read_config(PCIDevice *d,
void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l)
{
int i;
int i, was_irq_disabled = pci_irq_disabled(d);
uint32_t config_size = pci_config_size(d);
for (i = 0; i < l && addr + i < config_size; val >>= 8, ++i) {
......@@ -983,6 +1002,9 @@ void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l)
ranges_overlap(addr, l, PCI_ROM_ADDRESS1, 4) ||
range_covers_byte(addr, l, PCI_COMMAND))
pci_update_mappings(d);
if (range_covers_byte(addr, l, PCI_COMMAND))
pci_update_irq_disabled(d, was_irq_disabled);
}
/***********************************************************/
......@@ -1000,6 +1022,8 @@ static void pci_set_irq(void *opaque, int irq_num, int level)
pci_set_irq_state(pci_dev, irq_num, level);
pci_update_irq_status(pci_dev);
if (pci_irq_disabled(pci_dev))
return;
pci_change_irq_level(pci_dev, irq_num, change);
}
......
......@@ -92,77 +92,10 @@ typedef struct PCIIORegion {
#define PCI_ROM_SLOT 6
#define PCI_NUM_REGIONS 7
/* Declarations from linux/pci_regs.h */
#define PCI_VENDOR_ID 0x00 /* 16 bits */
#define PCI_DEVICE_ID 0x02 /* 16 bits */
#define PCI_COMMAND 0x04 /* 16 bits */
#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
#define PCI_COMMAND_MASTER 0x4 /* Enable bus master */
#define PCI_STATUS 0x06 /* 16 bits */
#define PCI_STATUS_INTERRUPT 0x08
#define PCI_REVISION_ID 0x08 /* 8 bits */
#define PCI_CLASS_PROG 0x09 /* Reg. Level Programming Interface */
#define PCI_CLASS_DEVICE 0x0a /* Device class */
#define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */
#define PCI_LATENCY_TIMER 0x0d /* 8 bits */
#define PCI_HEADER_TYPE 0x0e /* 8 bits */
#define PCI_HEADER_TYPE_NORMAL 0
#define PCI_HEADER_TYPE_BRIDGE 1
#define PCI_HEADER_TYPE_CARDBUS 2
#include "pci_regs.h"
/* PCI HEADER_TYPE */
#define PCI_HEADER_TYPE_MULTI_FUNCTION 0x80
#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */
#define PCI_BASE_ADDRESS_SPACE_IO 0x01
#define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */
#define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */
#define PCI_PRIMARY_BUS 0x18 /* Primary bus number */
#define PCI_SECONDARY_BUS 0x19 /* Secondary bus number */
#define PCI_SUBORDINATE_BUS 0x1a /* Highest bus number behind the bridge */
#define PCI_IO_BASE 0x1c /* I/O range behind the bridge */
#define PCI_IO_LIMIT 0x1d
#define PCI_IO_RANGE_TYPE_32 0x01
#define PCI_IO_RANGE_MASK (~0x0fUL)
#define PCI_SEC_STATUS 0x1e /* Secondary status register, only bit 14 used */
#define PCI_MEMORY_BASE 0x20 /* Memory range behind */
#define PCI_MEMORY_LIMIT 0x22
#define PCI_MEMORY_RANGE_MASK (~0x0fUL)
#define PCI_PREF_MEMORY_BASE 0x24 /* Prefetchable memory range behind */
#define PCI_PREF_MEMORY_LIMIT 0x26
#define PCI_PREF_RANGE_MASK (~0x0fUL)
#define PCI_PREF_RANGE_TYPE_64 0x01
#define PCI_PREF_BASE_UPPER32 0x28 /* Upper half of prefetchable memory range */
#define PCI_PREF_LIMIT_UPPER32 0x2c
#define PCI_SUBSYSTEM_VENDOR_ID 0x2c /* 16 bits */
#define PCI_SUBSYSTEM_ID 0x2e /* 16 bits */
#define PCI_ROM_ADDRESS 0x30 /* Bits 31..11 are address, 10..1 reserved */
#define PCI_ROM_ADDRESS_ENABLE 0x01
#define PCI_IO_BASE_UPPER16 0x30 /* Upper half of I/O addresses */
#define PCI_IO_LIMIT_UPPER16 0x32
#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */
#define PCI_ROM_ADDRESS1 0x38 /* Same as PCI_ROM_ADDRESS, but for htype 1 */
#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
#define PCI_MIN_GNT 0x3e /* 8 bits */
#define PCI_BRIDGE_CONTROL 0x3e
#define PCI_MAX_LAT 0x3f /* 8 bits */
/* Capability lists */
#define PCI_CAP_LIST_ID 0 /* Capability ID */
#define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */
#define PCI_REVISION 0x08 /* obsolete, use PCI_REVISION_ID */
#define PCI_SUBVENDOR_ID 0x2c /* obsolete, use PCI_SUBSYSTEM_VENDOR_ID */
#define PCI_SUBDEVICE_ID 0x2e /* obsolete, use PCI_SUBSYSTEM_ID */
/* Bits in the PCI Status Register (PCI 2.3 spec) */
#define PCI_STATUS_RESERVED1 0x007
#define PCI_STATUS_INT_STATUS 0x008
#define PCI_STATUS_CAP_LIST 0x010
#define PCI_STATUS_66MHZ 0x020
#define PCI_STATUS_RESERVED2 0x040
#define PCI_STATUS_FAST_BACK 0x080
#define PCI_STATUS_DEVSEL 0x600
#define PCI_STATUS_RESERVED_MASK_LO (PCI_STATUS_RESERVED1 | \
PCI_STATUS_INT_STATUS | PCI_STATUS_CAPABILITIES | \
......
此差异已折叠。
......@@ -1981,24 +1981,32 @@ static int pci_pcnet_init(PCIDevice *pci_dev)
pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_AMD);
pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_AMD_LANCE);
*(uint16_t *)&pci_conf[0x04] = cpu_to_le16(0x0007);
*(uint16_t *)&pci_conf[0x06] = cpu_to_le16(0x0280);
pci_conf[0x08] = 0x10;
pci_conf[0x09] = 0x00;
/* TODO: value should be 0 at RST# */
pci_set_word(pci_conf + PCI_COMMAND,
PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
pci_set_word(pci_conf + PCI_STATUS,
PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MEDIUM);
pci_conf[PCI_REVISION_ID] = 0x10;
/* TODO: 0 is the default anyway, no need to set it. */
pci_conf[PCI_CLASS_PROG] = 0x00;
pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
*(uint32_t *)&pci_conf[0x10] = cpu_to_le32(0x00000001);
*(uint32_t *)&pci_conf[0x14] = cpu_to_le32(0x00000000);
/* TODO: not necessary, is set when BAR is registered. */
pci_set_long(pci_conf + PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_SPACE_IO);
pci_set_long(pci_conf + PCI_BASE_ADDRESS_0 + 4,
PCI_BASE_ADDRESS_SPACE_MEMORY);
pci_conf[0x3d] = 1; // interrupt pin 0
pci_conf[0x3e] = 0x06;
pci_conf[0x3f] = 0xff;
/* TODO: value must be 0 at RST# */
pci_conf[PCI_INTERRUPT_PIN] = 1; // interrupt pin 0
pci_conf[PCI_MIN_GNT] = 0x06;
pci_conf[PCI_MAX_LAT] = 0xff;
/* Handler for memory-mapped I/O */
s->mmio_index =
cpu_register_io_memory(pcnet_mmio_read, pcnet_mmio_write, &d->state);
/* TODO: use pci_dev, avoid cast below. */
pci_register_bar((PCIDevice *)d, 0, PCNET_IOPORT_SIZE,
PCI_BASE_ADDRESS_SPACE_IO, pcnet_ioport_map);
......
......@@ -29,6 +29,11 @@
#include "isa.h"
#include "sysbus.h"
/*
* I440FX chipset data sheet.
* http://download.intel.com/design/chipsets/datashts/29054901.pdf
*/
typedef PCIHostState I440FXState;
typedef struct PIIX3State {
......@@ -44,6 +49,11 @@ struct PCII440FXState {
PIIX3State *piix3;
};
#define I440FX_PAM 0x59
#define I440FX_PAM_SIZE 7
#define I440FX_SMRAM 0x72
static void piix3_set_irq(void *opaque, int irq_num, int level);
/* return the global irq number corresponding to a given device irq
......@@ -88,12 +98,12 @@ static void i440fx_update_memory_mappings(PCII440FXState *d)
int i, r;
uint32_t smram, addr;
update_pam(d, 0xf0000, 0x100000, (d->dev.config[0x59] >> 4) & 3);
update_pam(d, 0xf0000, 0x100000, (d->dev.config[I440FX_PAM] >> 4) & 3);
for(i = 0; i < 12; i++) {
r = (d->dev.config[(i >> 1) + 0x5a] >> ((i & 1) * 4)) & 3;
r = (d->dev.config[(i >> 1) + (I440FX_PAM + 1)] >> ((i & 1) * 4)) & 3;
update_pam(d, 0xc0000 + 0x4000 * i, 0xc0000 + 0x4000 * (i + 1), r);
}
smram = d->dev.config[0x72];
smram = d->dev.config[I440FX_SMRAM];
if ((d->smm_enabled && (smram & 0x08)) || (smram & 0x40)) {
cpu_register_physical_memory(0xa0000, 0x20000, 0xa0000);
} else {
......@@ -132,8 +142,10 @@ static void i440fx_write_config(PCIDevice *dev,
/* XXX: implement SMRAM.D_LOCK */
pci_default_write_config(dev, address, val, len);
if ((address >= 0x59 && address <= 0x5f) || address == 0x72)
if (ranges_overlap(address, len, I440FX_PAM, I440FX_PAM_SIZE) ||
range_covers_byte(address, len, I440FX_SMRAM)) {
i440fx_update_memory_mappings(d);
}
}
static int i440fx_load_old(QEMUFile* f, void *opaque, int version_id)
......@@ -196,7 +208,7 @@ static int i440fx_initfn(PCIDevice *dev)
pci_config_set_class(d->dev.config, PCI_CLASS_BRIDGE_HOST);
d->dev.config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
d->dev.config[0x72] = 0x02; /* SMRAM */
d->dev.config[I440FX_SMRAM] = 0x02;
return 0;
}
......
......@@ -3320,16 +3320,20 @@ static int pci_rtl8139_init(PCIDevice *dev)
pci_conf = s->dev.config;
pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_REALTEK);
pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_REALTEK_8139);
pci_conf[0x04] = 0x05; /* command = I/O space, Bus Master */
pci_conf[0x08] = RTL8139_PCI_REVID; /* PCI revision ID; >=0x20 is for 8139C+ */
/* TODO: value should be 0 at RST#. */
pci_conf[PCI_COMMAND] = PCI_COMMAND_IO | PCI_COMMAND_MASTER;
pci_conf[PCI_REVISION_ID] = RTL8139_PCI_REVID; /* >=0x20 is for 8139C+ */
pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; /* header_type */
pci_conf[0x3d] = 1; /* interrupt pin 0 */
pci_conf[0x34] = 0xdc;
pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL;
/* TODO: value should be 0 at RST# */
pci_conf[PCI_INTERRUPT_PIN] = 1; /* interrupt pin 0 */
/* TODO: start of capability list, but no capability
* list bit in status register, and offset 0xdc seems unused. */
pci_conf[PCI_CAPABILITY_LIST] = 0xdc;
/* I/O handler for memory-mapped I/O */
s->rtl8139_mmio_io_addr =
cpu_register_io_memory(rtl8139_mmio_read, rtl8139_mmio_write, s);
cpu_register_io_memory(rtl8139_mmio_read, rtl8139_mmio_write, s);
pci_register_bar(&s->dev, 0, 0x100,
PCI_BASE_ADDRESS_SPACE_IO, rtl8139_ioport_map);
......
......@@ -1721,14 +1721,16 @@ static int usb_ohci_initfn_pci(struct PCIDevice *dev)
pci_config_set_vendor_id(ohci->pci_dev.config, PCI_VENDOR_ID_APPLE);
pci_config_set_device_id(ohci->pci_dev.config,
PCI_DEVICE_ID_APPLE_IPID_USB);
ohci->pci_dev.config[0x09] = 0x10; /* OHCI */
ohci->pci_dev.config[PCI_CLASS_PROG] = 0x10; /* OHCI */
pci_config_set_class(ohci->pci_dev.config, PCI_CLASS_SERIAL_USB);
ohci->pci_dev.config[0x3d] = 0x01; /* interrupt pin 1 */
/* TODO: RST# value should be 0. */
ohci->pci_dev.config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin 1 */
usb_ohci_init(&ohci->state, &dev->qdev, num_ports,
ohci->pci_dev.devfn, ohci->pci_dev.irq[0],
OHCI_TYPE_PCI, ohci->pci_dev.name, 0);
/* TODO: avoid cast below by using dev */
pci_register_bar((struct PCIDevice *)ohci, 0, 256,
PCI_BASE_ADDRESS_SPACE_MEMORY, ohci_mapfunc);
return 0;
......
......@@ -1065,11 +1065,12 @@ static int usb_uhci_common_initfn(UHCIState *s)
uint8_t *pci_conf = s->dev.config;
int i;
pci_conf[0x08] = 0x01; // revision number
pci_conf[0x09] = 0x00;
pci_conf[PCI_REVISION_ID] = 0x01; // revision number
pci_conf[PCI_CLASS_PROG] = 0x00;
pci_config_set_class(pci_conf, PCI_CLASS_SERIAL_USB);
pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
pci_conf[0x3d] = 4; // interrupt pin 3
/* TODO: reset value should be 0. */
pci_conf[PCI_INTERRUPT_PIN] = 4; // interrupt pin 3
pci_conf[0x60] = 0x10; // release number
usb_bus_new(&s->bus, &s->dev.qdev);
......
......@@ -1203,16 +1203,18 @@ static int pci_vmsvga_initfn(PCIDevice *dev)
pci_config_set_vendor_id(s->card.config, PCI_VENDOR_ID_VMWARE);
pci_config_set_device_id(s->card.config, SVGA_PCI_DEVICE_ID);
s->card.config[PCI_COMMAND] = 0x07; /* I/O + Memory */
s->card.config[PCI_COMMAND] = PCI_COMMAND_IO |
PCI_COMMAND_MEMORY |
PCI_COMMAND_MASTER; /* I/O + Memory */
pci_config_set_class(s->card.config, PCI_CLASS_DISPLAY_VGA);
s->card.config[0x0c] = 0x08; /* Cache line size */
s->card.config[0x0d] = 0x40; /* Latency timer */
s->card.config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL;
s->card.config[0x2c] = PCI_VENDOR_ID_VMWARE & 0xff;
s->card.config[0x2d] = PCI_VENDOR_ID_VMWARE >> 8;
s->card.config[0x2e] = SVGA_PCI_DEVICE_ID & 0xff;
s->card.config[0x2f] = SVGA_PCI_DEVICE_ID >> 8;
s->card.config[0x3c] = 0xff; /* End */
s->card.config[PCI_CACHE_LINE_SIZE] = 0x08; /* Cache line size */
s->card.config[PCI_LATENCY_TIMER] = 0x40; /* Latency timer */
s->card.config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL;
s->card.config[PCI_SUBSYSTEM_VENDOR_ID] = PCI_VENDOR_ID_VMWARE & 0xff;
s->card.config[PCI_SUBSYSTEM_VENDOR_ID + 1] = PCI_VENDOR_ID_VMWARE >> 8;
s->card.config[PCI_SUBSYSTEM_ID] = SVGA_PCI_DEVICE_ID & 0xff;
s->card.config[PCI_SUBSYSTEM_ID + 1] = SVGA_PCI_DEVICE_ID >> 8;
s->card.config[PCI_INTERRUPT_LINE] = 0xff; /* End */
pci_register_bar(&s->card, 0, 0x10,
PCI_BASE_ADDRESS_SPACE_IO, pci_vmsvga_map_ioport);
......
......@@ -411,7 +411,7 @@ static int i6300esb_init(PCIDevice *dev)
pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_ESB_9);
pci_config_set_class(pci_conf, PCI_CLASS_SYSTEM_OTHER);
pci_conf[0x0e] = 0x00;
pci_conf[PCI_HEADER_TYPE] = 0x00;
pci_register_bar(&d->dev, 0, 0x10,
PCI_BASE_ADDRESS_SPACE_MEMORY, i6300esb_map);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册