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