Skip to content

Commit

Permalink
Add TEWS TPCI200 IndustryPack emulation
Browse files Browse the repository at this point in the history
The TPCI200 is a PCI board that supports up to 4 IndustryPack modules.

A new bus type called 'IndustryPack' has been created so any
compatible module can be attached to this board.

Reviewed-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Alberto Garcia <agarcia@igalia.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
  • Loading branch information
bertogg authored and Anthony Liguori committed Jan 14, 2013
1 parent a507db9 commit 9c16fa7
Show file tree
Hide file tree
Showing 6 changed files with 872 additions and 0 deletions.
1 change: 1 addition & 0 deletions default-configs/pci.mak
Expand Up @@ -21,3 +21,4 @@ CONFIG_ESP=y
CONFIG_ESP_PCI=y
CONFIG_SERIAL=y
CONFIG_SERIAL_PCI=y
CONFIG_IPACK=y
3 changes: 3 additions & 0 deletions hw/Makefile.objs
Expand Up @@ -106,6 +106,9 @@ common-obj-$(CONFIG_XGMAC) += xgmac.o
# PCI watchdog devices
common-obj-$(CONFIG_PCI) += wdt_i6300esb.o

# IndustryPack
common-obj-$(CONFIG_IPACK) += tpci200.o ipack.o

# PCI network cards
common-obj-$(CONFIG_NE2000_PCI) += ne2000.o
common-obj-$(CONFIG_EEPRO100_PCI) += eepro100.o
Expand Down
115 changes: 115 additions & 0 deletions hw/ipack.c
@@ -0,0 +1,115 @@
/*
* QEMU IndustryPack emulation
*
* Copyright (C) 2012 Igalia, S.L.
* Author: Alberto Garcia <agarcia@igalia.com>
*
* This code is licensed under the GNU GPL v2 or (at your option) any
* later version.
*/

#include "ipack.h"

IPackDevice *ipack_device_find(IPackBus *bus, int32_t slot)
{
BusChild *kid;

QTAILQ_FOREACH(kid, &BUS(bus)->children, sibling) {
DeviceState *qdev = kid->child;
IPackDevice *ip = IPACK_DEVICE(qdev);
if (ip->slot == slot) {
return ip;
}
}
return NULL;
}

void ipack_bus_new_inplace(IPackBus *bus, DeviceState *parent,
const char *name, uint8_t n_slots,
qemu_irq_handler handler)
{
qbus_create_inplace(&bus->qbus, TYPE_IPACK_BUS, parent, name);
bus->n_slots = n_slots;
bus->set_irq = handler;
}

static int ipack_device_dev_init(DeviceState *qdev)
{
IPackBus *bus = IPACK_BUS(qdev_get_parent_bus(qdev));
IPackDevice *dev = IPACK_DEVICE(qdev);
IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(dev);

if (dev->slot < 0) {
dev->slot = bus->free_slot;
}
if (dev->slot >= bus->n_slots) {
return -1;
}
bus->free_slot = dev->slot + 1;

dev->irq = qemu_allocate_irqs(bus->set_irq, dev, 2);

return k->init(dev);
}

static int ipack_device_dev_exit(DeviceState *qdev)
{
IPackDevice *dev = IPACK_DEVICE(qdev);
IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(dev);

if (k->exit) {
k->exit(dev);
}

qemu_free_irqs(dev->irq);

return 0;
}

static Property ipack_device_props[] = {
DEFINE_PROP_INT32("slot", IPackDevice, slot, -1),
DEFINE_PROP_END_OF_LIST()
};

static void ipack_device_class_init(ObjectClass *klass, void *data)
{
DeviceClass *k = DEVICE_CLASS(klass);
k->bus_type = TYPE_IPACK_BUS;
k->init = ipack_device_dev_init;
k->exit = ipack_device_dev_exit;
k->props = ipack_device_props;
}

const VMStateDescription vmstate_ipack_device = {
.name = "ipack_device",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
VMSTATE_INT32(slot, IPackDevice),
VMSTATE_END_OF_LIST()
}
};

static const TypeInfo ipack_device_info = {
.name = TYPE_IPACK_DEVICE,
.parent = TYPE_DEVICE,
.instance_size = sizeof(IPackDevice),
.class_size = sizeof(IPackDeviceClass),
.class_init = ipack_device_class_init,
.abstract = true,
};

static const TypeInfo ipack_bus_info = {
.name = TYPE_IPACK_BUS,
.parent = TYPE_BUS,
.instance_size = sizeof(IPackBus),
};

static void ipack_register_types(void)
{
type_register_static(&ipack_device_info);
type_register_static(&ipack_bus_info);
}

type_init(ipack_register_types)
79 changes: 79 additions & 0 deletions hw/ipack.h
@@ -0,0 +1,79 @@
/*
* QEMU IndustryPack emulation
*
* Copyright (C) 2012 Igalia, S.L.
* Author: Alberto Garcia <agarcia@igalia.com>
*
* This code is licensed under the GNU GPL v2 or (at your option) any
* later version.
*/

#ifndef QEMU_IPACK_H
#define QEMU_IPACK_H

#include "qdev.h"

typedef struct IPackBus IPackBus;

#define TYPE_IPACK_BUS "IndustryPack"
#define IPACK_BUS(obj) OBJECT_CHECK(IPackBus, (obj), TYPE_IPACK_BUS)

struct IPackBus {
BusState qbus;
/* All fields are private */
uint8_t n_slots;
uint8_t free_slot;
qemu_irq_handler set_irq;
};

typedef struct IPackDevice IPackDevice;
typedef struct IPackDeviceClass IPackDeviceClass;

#define TYPE_IPACK_DEVICE "ipack-device"
#define IPACK_DEVICE(obj) \
OBJECT_CHECK(IPackDevice, (obj), TYPE_IPACK_DEVICE)
#define IPACK_DEVICE_CLASS(klass) \
OBJECT_CLASS_CHECK(IPackDeviceClass, (klass), TYPE_IPACK_DEVICE)
#define IPACK_DEVICE_GET_CLASS(obj) \
OBJECT_GET_CLASS(IPackDeviceClass, (obj), TYPE_IPACK_DEVICE)

struct IPackDeviceClass {
DeviceClass parent_class;

int (*init)(IPackDevice *dev);
int (*exit)(IPackDevice *dev);

uint16_t (*io_read)(IPackDevice *dev, uint8_t addr);
void (*io_write)(IPackDevice *dev, uint8_t addr, uint16_t val);

uint16_t (*id_read)(IPackDevice *dev, uint8_t addr);
void (*id_write)(IPackDevice *dev, uint8_t addr, uint16_t val);

uint16_t (*int_read)(IPackDevice *dev, uint8_t addr);
void (*int_write)(IPackDevice *dev, uint8_t addr, uint16_t val);

uint16_t (*mem_read16)(IPackDevice *dev, uint32_t addr);
void (*mem_write16)(IPackDevice *dev, uint32_t addr, uint16_t val);

uint8_t (*mem_read8)(IPackDevice *dev, uint32_t addr);
void (*mem_write8)(IPackDevice *dev, uint32_t addr, uint8_t val);
};

struct IPackDevice {
DeviceState qdev;
int32_t slot;
/* IRQ objects for the IndustryPack INT0# and INT1# */
qemu_irq *irq;
};

extern const VMStateDescription vmstate_ipack_device;

#define VMSTATE_IPACK_DEVICE(_field, _state) \
VMSTATE_STRUCT(_field, _state, 1, vmstate_ipack_device, IPackDevice)

IPackDevice *ipack_device_find(IPackBus *bus, int32_t slot);
void ipack_bus_new_inplace(IPackBus *bus, DeviceState *parent,
const char *name, uint8_t n_slots,
qemu_irq_handler handler);

#endif
3 changes: 3 additions & 0 deletions hw/pci/pci_ids.h
Expand Up @@ -148,4 +148,7 @@
#define PCI_VENDOR_ID_NEC 0x1033
#define PCI_DEVICE_ID_NEC_UPD720200 0x0194

#define PCI_VENDOR_ID_TEWS 0x1498
#define PCI_DEVICE_ID_TEWS_TPCI200 0x30C8

#endif

0 comments on commit 9c16fa7

Please sign in to comment.