mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-05 00:33:55 -06:00
pci: convert to QEMU Object Model
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
parent
6e4ec3f9bb
commit
40021f0888
53 changed files with 1591 additions and 1042 deletions
200
hw/eepro100.c
200
hw/eepro100.c
|
@ -128,7 +128,13 @@
|
|||
#define DRVR_INT 0x0200 /* Driver generated interrupt. */
|
||||
|
||||
typedef struct {
|
||||
PCIDeviceInfo pci;
|
||||
DeviceInfo qdev;
|
||||
|
||||
uint16_t device_id;
|
||||
uint8_t revision;
|
||||
uint16_t subsystem_vendor_id;
|
||||
uint16_t subsystem_id;
|
||||
|
||||
uint32_t device;
|
||||
uint8_t stats_size;
|
||||
bool has_extended_tcb_support;
|
||||
|
@ -318,6 +324,8 @@ static const uint16_t eepro100_mdi_mask[] = {
|
|||
|
||||
#define POLYNOMIAL 0x04c11db6
|
||||
|
||||
static E100PCIDeviceInfo *eepro100_get_class(EEPRO100State *s);
|
||||
|
||||
/* From FreeBSD */
|
||||
/* XXX: optimize */
|
||||
static unsigned compute_mcast_idx(const uint8_t * ep)
|
||||
|
@ -487,8 +495,9 @@ static void eepro100_fcp_interrupt(EEPRO100State * s)
|
|||
}
|
||||
#endif
|
||||
|
||||
static void e100_pci_reset(EEPRO100State * s, E100PCIDeviceInfo *e100_device)
|
||||
static void e100_pci_reset(EEPRO100State * s)
|
||||
{
|
||||
E100PCIDeviceInfo *info = eepro100_get_class(s);
|
||||
uint32_t device = s->device;
|
||||
uint8_t *pci_conf = s->dev.config;
|
||||
|
||||
|
@ -508,8 +517,8 @@ static void e100_pci_reset(EEPRO100State * s, E100PCIDeviceInfo *e100_device)
|
|||
/* Maximum Latency */
|
||||
pci_set_byte(pci_conf + PCI_MAX_LAT, 0x18);
|
||||
|
||||
s->stats_size = e100_device->stats_size;
|
||||
s->has_extended_tcb_support = e100_device->has_extended_tcb_support;
|
||||
s->stats_size = info->stats_size;
|
||||
s->has_extended_tcb_support = info->has_extended_tcb_support;
|
||||
|
||||
switch (device) {
|
||||
case i82550:
|
||||
|
@ -558,7 +567,7 @@ static void e100_pci_reset(EEPRO100State * s, E100PCIDeviceInfo *e100_device)
|
|||
}
|
||||
assert(s->stats_size > 0 && s->stats_size <= sizeof(s->statistics));
|
||||
|
||||
if (e100_device->power_management) {
|
||||
if (info->power_management) {
|
||||
/* Power Management Capabilities */
|
||||
int cfg_offset = 0xdc;
|
||||
int r = pci_add_capability(&s->dev, PCI_CAP_ID_PM,
|
||||
|
@ -1847,14 +1856,13 @@ static NetClientInfo net_eepro100_info = {
|
|||
static int e100_nic_init(PCIDevice *pci_dev)
|
||||
{
|
||||
EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
|
||||
E100PCIDeviceInfo *e100_device = DO_UPCAST(E100PCIDeviceInfo, pci.qdev,
|
||||
qdev_get_info(&pci_dev->qdev));
|
||||
E100PCIDeviceInfo *info = eepro100_get_class(s);
|
||||
|
||||
TRACE(OTHER, logout("\n"));
|
||||
|
||||
s->device = e100_device->device;
|
||||
s->device = info->device;
|
||||
|
||||
e100_pci_reset(s, e100_device);
|
||||
e100_pci_reset(s);
|
||||
|
||||
/* Add 64 * 2 EEPROM. i82557 and i82558 support a 64 word EEPROM,
|
||||
* i82559 and later support 64 or 256 word EEPROM. */
|
||||
|
@ -1897,136 +1905,182 @@ static int e100_nic_init(PCIDevice *pci_dev)
|
|||
|
||||
static E100PCIDeviceInfo e100_devices[] = {
|
||||
{
|
||||
.pci.qdev.name = "i82550",
|
||||
.pci.qdev.desc = "Intel i82550 Ethernet",
|
||||
.qdev.name = "i82550",
|
||||
.qdev.desc = "Intel i82550 Ethernet",
|
||||
.device = i82550,
|
||||
/* TODO: check device id. */
|
||||
.pci.device_id = PCI_DEVICE_ID_INTEL_82551IT,
|
||||
.device_id = PCI_DEVICE_ID_INTEL_82551IT,
|
||||
/* Revision ID: 0x0c, 0x0d, 0x0e. */
|
||||
.pci.revision = 0x0e,
|
||||
.revision = 0x0e,
|
||||
/* TODO: check size of statistical counters. */
|
||||
.stats_size = 80,
|
||||
/* TODO: check extended tcb support. */
|
||||
.has_extended_tcb_support = true,
|
||||
.power_management = true,
|
||||
},{
|
||||
.pci.qdev.name = "i82551",
|
||||
.pci.qdev.desc = "Intel i82551 Ethernet",
|
||||
.qdev.name = "i82551",
|
||||
.qdev.desc = "Intel i82551 Ethernet",
|
||||
.device = i82551,
|
||||
.pci.device_id = PCI_DEVICE_ID_INTEL_82551IT,
|
||||
.device_id = PCI_DEVICE_ID_INTEL_82551IT,
|
||||
/* Revision ID: 0x0f, 0x10. */
|
||||
.pci.revision = 0x0f,
|
||||
.revision = 0x0f,
|
||||
/* TODO: check size of statistical counters. */
|
||||
.stats_size = 80,
|
||||
.has_extended_tcb_support = true,
|
||||
.power_management = true,
|
||||
},{
|
||||
.pci.qdev.name = "i82557a",
|
||||
.pci.qdev.desc = "Intel i82557A Ethernet",
|
||||
.qdev.name = "i82557a",
|
||||
.qdev.desc = "Intel i82557A Ethernet",
|
||||
.device = i82557A,
|
||||
.pci.device_id = PCI_DEVICE_ID_INTEL_82557,
|
||||
.pci.revision = 0x01,
|
||||
.device_id = PCI_DEVICE_ID_INTEL_82557,
|
||||
.revision = 0x01,
|
||||
.power_management = false,
|
||||
},{
|
||||
.pci.qdev.name = "i82557b",
|
||||
.pci.qdev.desc = "Intel i82557B Ethernet",
|
||||
.qdev.name = "i82557b",
|
||||
.qdev.desc = "Intel i82557B Ethernet",
|
||||
.device = i82557B,
|
||||
.pci.device_id = PCI_DEVICE_ID_INTEL_82557,
|
||||
.pci.revision = 0x02,
|
||||
.device_id = PCI_DEVICE_ID_INTEL_82557,
|
||||
.revision = 0x02,
|
||||
.power_management = false,
|
||||
},{
|
||||
.pci.qdev.name = "i82557c",
|
||||
.pci.qdev.desc = "Intel i82557C Ethernet",
|
||||
.qdev.name = "i82557c",
|
||||
.qdev.desc = "Intel i82557C Ethernet",
|
||||
.device = i82557C,
|
||||
.pci.device_id = PCI_DEVICE_ID_INTEL_82557,
|
||||
.pci.revision = 0x03,
|
||||
.device_id = PCI_DEVICE_ID_INTEL_82557,
|
||||
.revision = 0x03,
|
||||
.power_management = false,
|
||||
},{
|
||||
.pci.qdev.name = "i82558a",
|
||||
.pci.qdev.desc = "Intel i82558A Ethernet",
|
||||
.qdev.name = "i82558a",
|
||||
.qdev.desc = "Intel i82558A Ethernet",
|
||||
.device = i82558A,
|
||||
.pci.device_id = PCI_DEVICE_ID_INTEL_82557,
|
||||
.pci.revision = 0x04,
|
||||
.device_id = PCI_DEVICE_ID_INTEL_82557,
|
||||
.revision = 0x04,
|
||||
.stats_size = 76,
|
||||
.has_extended_tcb_support = true,
|
||||
.power_management = true,
|
||||
},{
|
||||
.pci.qdev.name = "i82558b",
|
||||
.pci.qdev.desc = "Intel i82558B Ethernet",
|
||||
.qdev.name = "i82558b",
|
||||
.qdev.desc = "Intel i82558B Ethernet",
|
||||
.device = i82558B,
|
||||
.pci.device_id = PCI_DEVICE_ID_INTEL_82557,
|
||||
.pci.revision = 0x05,
|
||||
.device_id = PCI_DEVICE_ID_INTEL_82557,
|
||||
.revision = 0x05,
|
||||
.stats_size = 76,
|
||||
.has_extended_tcb_support = true,
|
||||
.power_management = true,
|
||||
},{
|
||||
.pci.qdev.name = "i82559a",
|
||||
.pci.qdev.desc = "Intel i82559A Ethernet",
|
||||
.qdev.name = "i82559a",
|
||||
.qdev.desc = "Intel i82559A Ethernet",
|
||||
.device = i82559A,
|
||||
.pci.device_id = PCI_DEVICE_ID_INTEL_82557,
|
||||
.pci.revision = 0x06,
|
||||
.device_id = PCI_DEVICE_ID_INTEL_82557,
|
||||
.revision = 0x06,
|
||||
.stats_size = 80,
|
||||
.has_extended_tcb_support = true,
|
||||
.power_management = true,
|
||||
},{
|
||||
.pci.qdev.name = "i82559b",
|
||||
.pci.qdev.desc = "Intel i82559B Ethernet",
|
||||
.qdev.name = "i82559b",
|
||||
.qdev.desc = "Intel i82559B Ethernet",
|
||||
.device = i82559B,
|
||||
.pci.device_id = PCI_DEVICE_ID_INTEL_82557,
|
||||
.pci.revision = 0x07,
|
||||
.device_id = PCI_DEVICE_ID_INTEL_82557,
|
||||
.revision = 0x07,
|
||||
.stats_size = 80,
|
||||
.has_extended_tcb_support = true,
|
||||
.power_management = true,
|
||||
},{
|
||||
.pci.qdev.name = "i82559c",
|
||||
.pci.qdev.desc = "Intel i82559C Ethernet",
|
||||
.qdev.name = "i82559c",
|
||||
.qdev.desc = "Intel i82559C Ethernet",
|
||||
.device = i82559C,
|
||||
.pci.device_id = PCI_DEVICE_ID_INTEL_82557,
|
||||
.device_id = PCI_DEVICE_ID_INTEL_82557,
|
||||
#if 0
|
||||
.pci.revision = 0x08,
|
||||
.revision = 0x08,
|
||||
#endif
|
||||
/* TODO: Windows wants revision id 0x0c. */
|
||||
.pci.revision = 0x0c,
|
||||
.revision = 0x0c,
|
||||
#if EEPROM_SIZE > 0
|
||||
.pci.subsystem_vendor_id = PCI_VENDOR_ID_INTEL,
|
||||
.pci.subsystem_id = 0x0040,
|
||||
.subsystem_vendor_id = PCI_VENDOR_ID_INTEL,
|
||||
.subsystem_id = 0x0040,
|
||||
#endif
|
||||
.stats_size = 80,
|
||||
.has_extended_tcb_support = true,
|
||||
.power_management = true,
|
||||
},{
|
||||
.pci.qdev.name = "i82559er",
|
||||
.pci.qdev.desc = "Intel i82559ER Ethernet",
|
||||
.qdev.name = "i82559er",
|
||||
.qdev.desc = "Intel i82559ER Ethernet",
|
||||
.device = i82559ER,
|
||||
.pci.device_id = PCI_DEVICE_ID_INTEL_82551IT,
|
||||
.pci.revision = 0x09,
|
||||
.device_id = PCI_DEVICE_ID_INTEL_82551IT,
|
||||
.revision = 0x09,
|
||||
.stats_size = 80,
|
||||
.has_extended_tcb_support = true,
|
||||
.power_management = true,
|
||||
},{
|
||||
.pci.qdev.name = "i82562",
|
||||
.pci.qdev.desc = "Intel i82562 Ethernet",
|
||||
.qdev.name = "i82562",
|
||||
.qdev.desc = "Intel i82562 Ethernet",
|
||||
.device = i82562,
|
||||
/* TODO: check device id. */
|
||||
.pci.device_id = PCI_DEVICE_ID_INTEL_82551IT,
|
||||
.device_id = PCI_DEVICE_ID_INTEL_82551IT,
|
||||
/* TODO: wrong revision id. */
|
||||
.pci.revision = 0x0e,
|
||||
.revision = 0x0e,
|
||||
.stats_size = 80,
|
||||
.has_extended_tcb_support = true,
|
||||
.power_management = true,
|
||||
},{
|
||||
/* Toshiba Tecra 8200. */
|
||||
.pci.qdev.name = "i82801",
|
||||
.pci.qdev.desc = "Intel i82801 Ethernet",
|
||||
.qdev.name = "i82801",
|
||||
.qdev.desc = "Intel i82801 Ethernet",
|
||||
.device = i82801,
|
||||
.pci.device_id = 0x2449,
|
||||
.pci.revision = 0x03,
|
||||
.device_id = 0x2449,
|
||||
.revision = 0x03,
|
||||
.stats_size = 80,
|
||||
.has_extended_tcb_support = true,
|
||||
.power_management = true,
|
||||
}
|
||||
};
|
||||
|
||||
static E100PCIDeviceInfo *eepro100_get_class_by_name(const char *typename)
|
||||
{
|
||||
E100PCIDeviceInfo *info = NULL;
|
||||
int i;
|
||||
|
||||
/* This is admittedly awkward but also temporary. QOM allows for
|
||||
* parameterized typing and for subclassing both of which would suitable
|
||||
* handle what's going on here. But class_data is already being used as
|
||||
* a stop-gap hack to allow incremental qdev conversion so we cannot use it
|
||||
* right now. Once we merge the final QOM series, we can come back here and
|
||||
* do this in a much more elegant fashion.
|
||||
*/
|
||||
for (i = 0; i < ARRAY_SIZE(e100_devices); i++) {
|
||||
if (strcmp(e100_devices[i].qdev.name, typename) == 0) {
|
||||
info = &e100_devices[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(info != NULL);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
static E100PCIDeviceInfo *eepro100_get_class(EEPRO100State *s)
|
||||
{
|
||||
return eepro100_get_class_by_name(object_get_typename(OBJECT(s)));
|
||||
}
|
||||
|
||||
static void eepro100_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
||||
E100PCIDeviceInfo *info;
|
||||
|
||||
info = eepro100_get_class_by_name(object_class_get_name(klass));
|
||||
|
||||
k->vendor_id = PCI_VENDOR_ID_INTEL;
|
||||
k->class_id = PCI_CLASS_NETWORK_ETHERNET;
|
||||
k->romfile = "pxe-eepro100.rom";
|
||||
k->init = e100_nic_init;
|
||||
k->exit = pci_nic_uninit;
|
||||
k->device_id = info->device_id;
|
||||
k->revision = info->revision;
|
||||
k->subsystem_vendor_id = info->subsystem_vendor_id;
|
||||
k->subsystem_id = info->subsystem_id;
|
||||
}
|
||||
|
||||
static Property e100_properties[] = {
|
||||
DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
|
@ -2036,17 +2090,13 @@ static void eepro100_register_devices(void)
|
|||
{
|
||||
size_t i;
|
||||
for (i = 0; i < ARRAY_SIZE(e100_devices); i++) {
|
||||
PCIDeviceInfo *pci_dev = &e100_devices[i].pci;
|
||||
/* We use the same rom file for all device ids.
|
||||
QEMU fixes the device id during rom load. */
|
||||
pci_dev->vendor_id = PCI_VENDOR_ID_INTEL;
|
||||
pci_dev->class_id = PCI_CLASS_NETWORK_ETHERNET;
|
||||
pci_dev->romfile = "pxe-eepro100.rom";
|
||||
pci_dev->init = e100_nic_init;
|
||||
pci_dev->exit = pci_nic_uninit;
|
||||
pci_dev->qdev.props = e100_properties;
|
||||
pci_dev->qdev.size = sizeof(EEPRO100State);
|
||||
pci_qdev_register(pci_dev);
|
||||
DeviceInfo *info = &e100_devices[i].qdev;
|
||||
|
||||
info->class_init = eepro100_class_init;
|
||||
info->size = sizeof(EEPRO100State);
|
||||
info->props = e100_properties;
|
||||
|
||||
pci_qdev_register(info);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue