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