tpci200.c 19 KB

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