qemu/hw/ipack/tpci200.c
<<
>>
Prefs
   1/*
   2 * QEMU TEWS TPCI200 IndustryPack carrier emulation
   3 *
   4 * Copyright (C) 2012 Igalia, S.L.
   5 * Author: Alberto Garcia <berto@igalia.com>
   6 *
   7 * This code is licensed under the GNU GPL v2 or (at your option) any
   8 * later version.
   9 */
  10
  11#include "qemu/osdep.h"
  12#include "hw/ipack/ipack.h"
  13#include "hw/pci/pci.h"
  14#include "qemu/bitops.h"
  15
  16/* #define DEBUG_TPCI */
  17
  18#ifdef DEBUG_TPCI
  19#define DPRINTF(fmt, ...) \
  20    do { fprintf(stderr, "TPCI200: " fmt, ## __VA_ARGS__); } while (0)
  21#else
  22#define DPRINTF(fmt, ...) do { } while (0)
  23#endif
  24
  25#define N_MODULES 4
  26
  27#define IP_ID_SPACE  2
  28#define IP_INT_SPACE 3
  29#define IP_IO_SPACE_ADDR_MASK  0x7F
  30#define IP_ID_SPACE_ADDR_MASK  0x3F
  31#define IP_INT_SPACE_ADDR_MASK 0x3F
  32
  33#define STATUS_INT(IP, INTNO) BIT((IP) * 2 + (INTNO))
  34#define STATUS_TIME(IP)       BIT((IP) + 12)
  35#define STATUS_ERR_ANY        0xF00
  36
  37#define CTRL_CLKRATE          BIT(0)
  38#define CTRL_RECOVER          BIT(1)
  39#define CTRL_TIME_INT         BIT(2)
  40#define CTRL_ERR_INT          BIT(3)
  41#define CTRL_INT_EDGE(INTNO)  BIT(4 + (INTNO))
  42#define CTRL_INT(INTNO)       BIT(6 + (INTNO))
  43
  44#define REG_REV_ID    0x00
  45#define REG_IP_A_CTRL 0x02
  46#define REG_IP_B_CTRL 0x04
  47#define REG_IP_C_CTRL 0x06
  48#define REG_IP_D_CTRL 0x08
  49#define REG_RESET     0x0A
  50#define REG_STATUS    0x0C
  51#define IP_N_FROM_REG(REG) ((REG) / 2 - 1)
  52
  53typedef struct {
  54    PCIDevice dev;
  55    IPackBus bus;
  56    MemoryRegion mmio;
  57    MemoryRegion io;
  58    MemoryRegion las0;
  59    MemoryRegion las1;
  60    MemoryRegion las2;
  61    MemoryRegion las3;
  62    bool big_endian[3];
  63    uint8_t ctrl[N_MODULES];
  64    uint16_t status;
  65    uint8_t int_set;
  66} TPCI200State;
  67
  68#define TYPE_TPCI200 "tpci200"
  69
  70#define TPCI200(obj) \
  71    OBJECT_CHECK(TPCI200State, (obj), TYPE_TPCI200)
  72
  73static const uint8_t local_config_regs[] = {
  74    0x00, 0xFF, 0xFF, 0x0F, 0x00, 0xFC, 0xFF, 0x0F, 0x00, 0x00, 0x00,
  75    0x0E, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
  76    0x00, 0x08, 0x01, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x01,
  77    0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x60, 0x41, 0xD4,
  78    0xA2, 0x20, 0x41, 0x14, 0xA2, 0x20, 0x41, 0x14, 0xA2, 0x20, 0x01,
  79    0x14, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x08, 0x01, 0x02,
  80    0x00, 0x04, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x80, 0x02, 0x41,
  81    0x00, 0x00, 0x00, 0x00, 0x40, 0x7A, 0x00, 0x52, 0x92, 0x24, 0x02
  82};
  83
  84static void adjust_addr(bool big_endian, hwaddr *addr, unsigned size)
  85{
  86    /* During 8 bit access in big endian mode,
  87       odd and even addresses are swapped */
  88    if (big_endian && size == 1) {
  89        *addr ^= 1;
  90    }
  91}
  92
  93static uint64_t adjust_value(bool big_endian, uint64_t *val, unsigned size)
  94{
  95    /* Local spaces only support 8/16 bit access,
  96     * so there's no need to care for sizes > 2 */
  97    if (big_endian && size == 2) {
  98        *val = bswap16(*val);
  99    }
 100    return *val;
 101}
 102
 103static void tpci200_set_irq(void *opaque, int intno, int level)
 104{
 105    IPackDevice *ip = opaque;
 106    IPackBus *bus = IPACK_BUS(qdev_get_parent_bus(DEVICE(ip)));
 107    PCIDevice *pcidev = PCI_DEVICE(BUS(bus)->parent);
 108    TPCI200State *dev = TPCI200(pcidev);
 109    unsigned ip_n = ip->slot;
 110    uint16_t prev_status = dev->status;
 111
 112    assert(ip->slot >= 0 && ip->slot < N_MODULES);
 113
 114    /* The requested interrupt must be enabled in the IP CONTROL
 115     * register */
 116    if (!(dev->ctrl[ip_n] & CTRL_INT(intno))) {
 117        return;
 118    }
 119
 120    /* Update the interrupt status in the IP STATUS register */
 121    if (level) {
 122        dev->status |=  STATUS_INT(ip_n, intno);
 123    } else {
 124        dev->status &= ~STATUS_INT(ip_n, intno);
 125    }
 126
 127    /* Return if there are no changes */
 128    if (dev->status == prev_status) {
 129        return;
 130    }
 131
 132    DPRINTF("IP %u INT%u#: %u\n", ip_n, intno, level);
 133
 134    /* Check if the interrupt is edge sensitive */
 135    if (dev->ctrl[ip_n] & CTRL_INT_EDGE(intno)) {
 136        if (level) {
 137            pci_set_irq(&dev->dev, !dev->int_set);
 138            pci_set_irq(&dev->dev,  dev->int_set);
 139        }
 140    } else {
 141        unsigned i, j;
 142        uint16_t level_status = dev->status;
 143
 144        /* Check if there are any level sensitive interrupts set by
 145           removing the ones that are edge sensitive from the status
 146           register */
 147        for (i = 0; i < N_MODULES; i++) {
 148            for (j = 0; j < 2; j++) {
 149                if (dev->ctrl[i] & CTRL_INT_EDGE(j)) {
 150                    level_status &= ~STATUS_INT(i, j);
 151                }
 152            }
 153        }
 154
 155        if (level_status && !dev->int_set) {
 156            pci_irq_assert(&dev->dev);
 157            dev->int_set = 1;
 158        } else if (!level_status && dev->int_set) {
 159            pci_irq_deassert(&dev->dev);
 160            dev->int_set = 0;
 161        }
 162    }
 163}
 164
 165static uint64_t tpci200_read_cfg(void *opaque, hwaddr addr, unsigned size)
 166{
 167    TPCI200State *s = opaque;
 168    uint8_t ret = 0;
 169    if (addr < ARRAY_SIZE(local_config_regs)) {
 170        ret = local_config_regs[addr];
 171    }
 172    /* Endianness is stored in the first bit of these registers */
 173    if ((addr == 0x2b && s->big_endian[0]) ||
 174        (addr == 0x2f && s->big_endian[1]) ||
 175        (addr == 0x33 && s->big_endian[2])) {
 176        ret |= 1;
 177    }
 178    DPRINTF("Read from LCR 0x%x: 0x%x\n", (unsigned) addr, (unsigned) ret);
 179    return ret;
 180}
 181
 182static void tpci200_write_cfg(void *opaque, hwaddr addr, uint64_t val,
 183                              unsigned size)
 184{
 185    TPCI200State *s = opaque;
 186    /* Endianness is stored in the first bit of these registers */
 187    if (addr == 0x2b || addr == 0x2f || addr == 0x33) {
 188        unsigned las = (addr - 0x2b) / 4;
 189        s->big_endian[las] = val & 1;
 190        DPRINTF("LAS%u big endian mode: %u\n", las, (unsigned) val & 1);
 191    } else {
 192        DPRINTF("Write to LCR 0x%x: 0x%x\n", (unsigned) addr, (unsigned) val);
 193    }
 194}
 195
 196static uint64_t tpci200_read_las0(void *opaque, hwaddr addr, unsigned size)
 197{
 198    TPCI200State *s = opaque;
 199    uint64_t ret = 0;
 200
 201    switch (addr) {
 202
 203    case REG_REV_ID:
 204        DPRINTF("Read REVISION ID\n"); /* Current value is 0x00 */
 205        break;
 206
 207    case REG_IP_A_CTRL:
 208    case REG_IP_B_CTRL:
 209    case REG_IP_C_CTRL:
 210    case REG_IP_D_CTRL:
 211        {
 212            unsigned ip_n = IP_N_FROM_REG(addr);
 213            ret = s->ctrl[ip_n];
 214            DPRINTF("Read IP %c CONTROL: 0x%x\n", 'A' + ip_n, (unsigned) ret);
 215        }
 216        break;
 217
 218    case REG_RESET:
 219        DPRINTF("Read RESET\n"); /* Not implemented */
 220        break;
 221
 222    case REG_STATUS:
 223        ret = s->status;
 224        DPRINTF("Read STATUS: 0x%x\n", (unsigned) ret);
 225        break;
 226
 227    /* Reserved */
 228    default:
 229        DPRINTF("Unsupported read from LAS0 0x%x\n", (unsigned) addr);
 230        break;
 231    }
 232
 233    return adjust_value(s->big_endian[0], &ret, size);
 234}
 235
 236static void tpci200_write_las0(void *opaque, hwaddr addr, uint64_t val,
 237                               unsigned size)
 238{
 239    TPCI200State *s = opaque;
 240
 241    adjust_value(s->big_endian[0], &val, size);
 242
 243    switch (addr) {
 244
 245    case REG_REV_ID:
 246        DPRINTF("Write Revision ID: 0x%x\n", (unsigned) val); /* No effect */
 247        break;
 248
 249    case REG_IP_A_CTRL:
 250    case REG_IP_B_CTRL:
 251    case REG_IP_C_CTRL:
 252    case REG_IP_D_CTRL:
 253        {
 254            unsigned ip_n = IP_N_FROM_REG(addr);
 255            s->ctrl[ip_n] = val;
 256            DPRINTF("Write IP %c CONTROL: 0x%x\n", 'A' + ip_n, (unsigned) val);
 257        }
 258        break;
 259
 260    case REG_RESET:
 261        DPRINTF("Write RESET: 0x%x\n", (unsigned) val); /* Not implemented */
 262        break;
 263
 264    case REG_STATUS:
 265        {
 266            unsigned i;
 267
 268            for (i = 0; i < N_MODULES; i++) {
 269                IPackDevice *ip = ipack_device_find(&s->bus, i);
 270
 271                if (ip != NULL) {
 272                    if (val & STATUS_INT(i, 0)) {
 273                        DPRINTF("Clear IP %c INT0# status\n", 'A' + i);
 274                        qemu_irq_lower(ip->irq[0]);
 275                    }
 276                    if (val & STATUS_INT(i, 1)) {
 277                        DPRINTF("Clear IP %c INT1# status\n", 'A' + i);
 278                        qemu_irq_lower(ip->irq[1]);
 279                    }
 280                }
 281
 282                if (val & STATUS_TIME(i)) {
 283                    DPRINTF("Clear IP %c timeout\n", 'A' + i);
 284                    s->status &= ~STATUS_TIME(i);
 285                }
 286            }
 287
 288            if (val & STATUS_ERR_ANY) {
 289                DPRINTF("Unexpected write to STATUS register: 0x%x\n",
 290                        (unsigned) val);
 291            }
 292        }
 293        break;
 294
 295    /* Reserved */
 296    default:
 297        DPRINTF("Unsupported write to LAS0 0x%x: 0x%x\n",
 298                (unsigned) addr, (unsigned) val);
 299        break;
 300    }
 301}
 302
 303static uint64_t tpci200_read_las1(void *opaque, hwaddr addr, unsigned size)
 304{
 305    TPCI200State *s = opaque;
 306    IPackDevice *ip;
 307    uint64_t ret = 0;
 308    unsigned ip_n, space;
 309    uint8_t offset;
 310
 311    adjust_addr(s->big_endian[1], &addr, size);
 312
 313    /*
 314     * The address is divided into the IP module number (0-4), the IP
 315     * address space (I/O, ID, INT) and the offset within that space.
 316     */
 317    ip_n = addr >> 8;
 318    space = (addr >> 6) & 3;
 319    ip = ipack_device_find(&s->bus, ip_n);
 320
 321    if (ip == NULL) {
 322        DPRINTF("Read LAS1: IP module %u not installed\n", ip_n);
 323    } else {
 324        IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(ip);
 325        switch (space) {
 326
 327        case IP_ID_SPACE:
 328            offset = addr & IP_ID_SPACE_ADDR_MASK;
 329            if (k->id_read) {
 330                ret = k->id_read(ip, offset);
 331            }
 332            break;
 333
 334        case IP_INT_SPACE:
 335            offset = addr & IP_INT_SPACE_ADDR_MASK;
 336
 337            /* Read address 0 to ACK IP INT0# and address 2 to ACK IP INT1# */
 338            if (offset == 0 || offset == 2) {
 339                unsigned intno = offset / 2;
 340                bool int_set = s->status & STATUS_INT(ip_n, intno);
 341                bool int_edge_sensitive = s->ctrl[ip_n] & CTRL_INT_EDGE(intno);
 342                if (int_set && !int_edge_sensitive) {
 343                    qemu_irq_lower(ip->irq[intno]);
 344                }
 345            }
 346
 347            if (k->int_read) {
 348                ret = k->int_read(ip, offset);
 349            }
 350            break;
 351
 352        default:
 353            offset = addr & IP_IO_SPACE_ADDR_MASK;
 354            if (k->io_read) {
 355                ret = k->io_read(ip, offset);
 356            }
 357            break;
 358        }
 359    }
 360
 361    return adjust_value(s->big_endian[1], &ret, size);
 362}
 363
 364static void tpci200_write_las1(void *opaque, hwaddr addr, uint64_t val,
 365                               unsigned size)
 366{
 367    TPCI200State *s = opaque;
 368    IPackDevice *ip;
 369    unsigned ip_n, space;
 370    uint8_t offset;
 371
 372    adjust_addr(s->big_endian[1], &addr, size);
 373    adjust_value(s->big_endian[1], &val, size);
 374
 375    /*
 376     * The address is divided into the IP module number, the IP
 377     * address space (I/O, ID, INT) and the offset within that space.
 378     */
 379    ip_n = addr >> 8;
 380    space = (addr >> 6) & 3;
 381    ip = ipack_device_find(&s->bus, ip_n);
 382
 383    if (ip == NULL) {
 384        DPRINTF("Write LAS1: IP module %u not installed\n", ip_n);
 385    } else {
 386        IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(ip);
 387        switch (space) {
 388
 389        case IP_ID_SPACE:
 390            offset = addr & IP_ID_SPACE_ADDR_MASK;
 391            if (k->id_write) {
 392                k->id_write(ip, offset, val);
 393            }
 394            break;
 395
 396        case IP_INT_SPACE:
 397            offset = addr & IP_INT_SPACE_ADDR_MASK;
 398            if (k->int_write) {
 399                k->int_write(ip, offset, val);
 400            }
 401            break;
 402
 403        default:
 404            offset = addr & IP_IO_SPACE_ADDR_MASK;
 405            if (k->io_write) {
 406                k->io_write(ip, offset, val);
 407            }
 408            break;
 409        }
 410    }
 411}
 412
 413static uint64_t tpci200_read_las2(void *opaque, hwaddr addr, unsigned size)
 414{
 415    TPCI200State *s = opaque;
 416    IPackDevice *ip;
 417    uint64_t ret = 0;
 418    unsigned ip_n;
 419    uint32_t offset;
 420
 421    adjust_addr(s->big_endian[2], &addr, size);
 422
 423    /*
 424     * The address is divided into the IP module number and the offset
 425     * within the IP module MEM space.
 426     */
 427    ip_n = addr >> 23;
 428    offset = addr & 0x7fffff;
 429    ip = ipack_device_find(&s->bus, ip_n);
 430
 431    if (ip == NULL) {
 432        DPRINTF("Read LAS2: IP module %u not installed\n", ip_n);
 433    } else {
 434        IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(ip);
 435        if (k->mem_read16) {
 436            ret = k->mem_read16(ip, offset);
 437        }
 438    }
 439
 440    return adjust_value(s->big_endian[2], &ret, size);
 441}
 442
 443static void tpci200_write_las2(void *opaque, hwaddr addr, uint64_t val,
 444                               unsigned size)
 445{
 446    TPCI200State *s = opaque;
 447    IPackDevice *ip;
 448    unsigned ip_n;
 449    uint32_t offset;
 450
 451    adjust_addr(s->big_endian[2], &addr, size);
 452    adjust_value(s->big_endian[2], &val, size);
 453
 454    /*
 455     * The address is divided into the IP module number and the offset
 456     * within the IP module MEM space.
 457     */
 458    ip_n = addr >> 23;
 459    offset = addr & 0x7fffff;
 460    ip = ipack_device_find(&s->bus, ip_n);
 461
 462    if (ip == NULL) {
 463        DPRINTF("Write LAS2: IP module %u not installed\n", ip_n);
 464    } else {
 465        IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(ip);
 466        if (k->mem_write16) {
 467            k->mem_write16(ip, offset, val);
 468        }
 469    }
 470}
 471
 472static uint64_t tpci200_read_las3(void *opaque, hwaddr addr, unsigned size)
 473{
 474    TPCI200State *s = opaque;
 475    IPackDevice *ip;
 476    uint64_t ret = 0;
 477    /*
 478     * The address is divided into the IP module number and the offset
 479     * within the IP module MEM space.
 480     */
 481    unsigned ip_n = addr >> 22;
 482    uint32_t offset = addr & 0x3fffff;
 483
 484    ip = ipack_device_find(&s->bus, ip_n);
 485
 486    if (ip == NULL) {
 487        DPRINTF("Read LAS3: IP module %u not installed\n", ip_n);
 488    } else {
 489        IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(ip);
 490        if (k->mem_read8) {
 491            ret = k->mem_read8(ip, offset);
 492        }
 493    }
 494
 495    return ret;
 496}
 497
 498static void tpci200_write_las3(void *opaque, hwaddr addr, uint64_t val,
 499                               unsigned size)
 500{
 501    TPCI200State *s = opaque;
 502    IPackDevice *ip;
 503    /*
 504     * The address is divided into the IP module number and the offset
 505     * within the IP module MEM space.
 506     */
 507    unsigned ip_n = addr >> 22;
 508    uint32_t offset = addr & 0x3fffff;
 509
 510    ip = ipack_device_find(&s->bus, ip_n);
 511
 512    if (ip == NULL) {
 513        DPRINTF("Write LAS3: IP module %u not installed\n", ip_n);
 514    } else {
 515        IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(ip);
 516        if (k->mem_write8) {
 517            k->mem_write8(ip, offset, val);
 518        }
 519    }
 520}
 521
 522static const MemoryRegionOps tpci200_cfg_ops = {
 523    .read = tpci200_read_cfg,
 524    .write = tpci200_write_cfg,
 525    .endianness = DEVICE_NATIVE_ENDIAN,
 526    .valid =  {
 527        .min_access_size = 1,
 528        .max_access_size = 4
 529    },
 530    .impl = {
 531        .min_access_size = 1,
 532        .max_access_size = 1
 533    }
 534};
 535
 536static const MemoryRegionOps tpci200_las0_ops = {
 537    .read = tpci200_read_las0,
 538    .write = tpci200_write_las0,
 539    .endianness = DEVICE_NATIVE_ENDIAN,
 540    .valid =  {
 541        .min_access_size = 2,
 542        .max_access_size = 2
 543    }
 544};
 545
 546static const MemoryRegionOps tpci200_las1_ops = {
 547    .read = tpci200_read_las1,
 548    .write = tpci200_write_las1,
 549    .endianness = DEVICE_NATIVE_ENDIAN,
 550    .valid =  {
 551        .min_access_size = 1,
 552        .max_access_size = 2
 553    }
 554};
 555
 556static const MemoryRegionOps tpci200_las2_ops = {
 557    .read = tpci200_read_las2,
 558    .write = tpci200_write_las2,
 559    .endianness = DEVICE_NATIVE_ENDIAN,
 560    .valid =  {
 561        .min_access_size = 1,
 562        .max_access_size = 2
 563    }
 564};
 565
 566static const MemoryRegionOps tpci200_las3_ops = {
 567    .read = tpci200_read_las3,
 568    .write = tpci200_write_las3,
 569    .endianness = DEVICE_NATIVE_ENDIAN,
 570    .valid =  {
 571        .min_access_size = 1,
 572        .max_access_size = 1
 573    }
 574};
 575
 576static void tpci200_realize(PCIDevice *pci_dev, Error **errp)
 577{
 578    TPCI200State *s = TPCI200(pci_dev);
 579    uint8_t *c = s->dev.config;
 580
 581    pci_set_word(c + PCI_COMMAND, 0x0003);
 582    pci_set_word(c + PCI_STATUS,  0x0280);
 583
 584    pci_set_byte(c + PCI_INTERRUPT_PIN, 0x01); /* Interrupt pin A */
 585
 586    pci_set_byte(c + PCI_CAPABILITY_LIST, 0x40);
 587    pci_set_long(c + 0x40, 0x48014801);
 588    pci_set_long(c + 0x48, 0x00024C06);
 589    pci_set_long(c + 0x4C, 0x00000003);
 590
 591    memory_region_init_io(&s->mmio, OBJECT(s), &tpci200_cfg_ops,
 592                          s, "tpci200_mmio", 128);
 593    memory_region_init_io(&s->io, OBJECT(s),   &tpci200_cfg_ops,
 594                          s, "tpci200_io",   128);
 595    memory_region_init_io(&s->las0, OBJECT(s), &tpci200_las0_ops,
 596                          s, "tpci200_las0", 256);
 597    memory_region_init_io(&s->las1, OBJECT(s), &tpci200_las1_ops,
 598                          s, "tpci200_las1", 1024);
 599    memory_region_init_io(&s->las2, OBJECT(s), &tpci200_las2_ops,
 600                          s, "tpci200_las2", 1024*1024*32);
 601    memory_region_init_io(&s->las3, OBJECT(s), &tpci200_las3_ops,
 602                          s, "tpci200_las3", 1024*1024*16);
 603    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio);
 604    pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO,     &s->io);
 605    pci_register_bar(&s->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->las0);
 606    pci_register_bar(&s->dev, 3, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->las1);
 607    pci_register_bar(&s->dev, 4, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->las2);
 608    pci_register_bar(&s->dev, 5, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->las3);
 609
 610    ipack_bus_new_inplace(&s->bus, sizeof(s->bus), DEVICE(pci_dev), NULL,
 611                          N_MODULES, tpci200_set_irq);
 612}
 613
 614static const VMStateDescription vmstate_tpci200 = {
 615    .name = "tpci200",
 616    .version_id = 1,
 617    .minimum_version_id = 1,
 618    .fields = (VMStateField[]) {
 619        VMSTATE_PCI_DEVICE(dev, TPCI200State),
 620        VMSTATE_BOOL_ARRAY(big_endian, TPCI200State, 3),
 621        VMSTATE_UINT8_ARRAY(ctrl, TPCI200State, N_MODULES),
 622        VMSTATE_UINT16(status, TPCI200State),
 623        VMSTATE_UINT8(int_set, TPCI200State),
 624        VMSTATE_END_OF_LIST()
 625    }
 626};
 627
 628static void tpci200_class_init(ObjectClass *klass, void *data)
 629{
 630    DeviceClass *dc = DEVICE_CLASS(klass);
 631    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 632
 633    k->realize = tpci200_realize;
 634    k->vendor_id = PCI_VENDOR_ID_TEWS;
 635    k->device_id = PCI_DEVICE_ID_TEWS_TPCI200;
 636    k->class_id = PCI_CLASS_BRIDGE_OTHER;
 637    k->subsystem_vendor_id = PCI_VENDOR_ID_TEWS;
 638    k->subsystem_id = 0x300A;
 639    set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
 640    dc->desc = "TEWS TPCI200 IndustryPack carrier";
 641    dc->vmsd = &vmstate_tpci200;
 642}
 643
 644static const TypeInfo tpci200_info = {
 645    .name          = TYPE_TPCI200,
 646    .parent        = TYPE_PCI_DEVICE,
 647    .instance_size = sizeof(TPCI200State),
 648    .class_init    = tpci200_class_init,
 649};
 650
 651static void tpci200_register_types(void)
 652{
 653    type_register_static(&tpci200_info);
 654}
 655
 656type_init(tpci200_register_types)
 657