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