2
0

parallel.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646
  1. /*
  2. * QEMU Parallel PORT emulation
  3. *
  4. * Copyright (c) 2003-2005 Fabrice Bellard
  5. * Copyright (c) 2007 Marko Kohtala
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy
  8. * of this software and associated documentation files (the "Software"), to deal
  9. * in the Software without restriction, including without limitation the rights
  10. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. * copies of the Software, and to permit persons to whom the Software is
  12. * furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in
  15. * all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. * THE SOFTWARE.
  24. */
  25. #include "qemu/osdep.h"
  26. #include "qapi/error.h"
  27. #include "qemu/module.h"
  28. #include "chardev/char-parallel.h"
  29. #include "chardev/char-fe.h"
  30. #include "hw/irq.h"
  31. #include "hw/isa/isa.h"
  32. #include "hw/qdev-properties.h"
  33. #include "migration/vmstate.h"
  34. #include "hw/char/parallel.h"
  35. #include "sysemu/reset.h"
  36. #include "sysemu/sysemu.h"
  37. #include "trace.h"
  38. //#define DEBUG_PARALLEL
  39. #ifdef DEBUG_PARALLEL
  40. #define pdebug(fmt, ...) printf("pp: " fmt, ## __VA_ARGS__)
  41. #else
  42. #define pdebug(fmt, ...) ((void)0)
  43. #endif
  44. #define PARA_REG_DATA 0
  45. #define PARA_REG_STS 1
  46. #define PARA_REG_CTR 2
  47. #define PARA_REG_EPP_ADDR 3
  48. #define PARA_REG_EPP_DATA 4
  49. /*
  50. * These are the definitions for the Printer Status Register
  51. */
  52. #define PARA_STS_BUSY 0x80 /* Busy complement */
  53. #define PARA_STS_ACK 0x40 /* Acknowledge */
  54. #define PARA_STS_PAPER 0x20 /* Out of paper */
  55. #define PARA_STS_ONLINE 0x10 /* Online */
  56. #define PARA_STS_ERROR 0x08 /* Error complement */
  57. #define PARA_STS_TMOUT 0x01 /* EPP timeout */
  58. /*
  59. * These are the definitions for the Printer Control Register
  60. */
  61. #define PARA_CTR_DIR 0x20 /* Direction (1=read, 0=write) */
  62. #define PARA_CTR_INTEN 0x10 /* IRQ Enable */
  63. #define PARA_CTR_SELECT 0x08 /* Select In complement */
  64. #define PARA_CTR_INIT 0x04 /* Initialize Printer complement */
  65. #define PARA_CTR_AUTOLF 0x02 /* Auto linefeed complement */
  66. #define PARA_CTR_STROBE 0x01 /* Strobe complement */
  67. #define PARA_CTR_SIGNAL (PARA_CTR_SELECT|PARA_CTR_INIT|PARA_CTR_AUTOLF|PARA_CTR_STROBE)
  68. typedef struct ParallelState {
  69. MemoryRegion iomem;
  70. uint8_t dataw;
  71. uint8_t datar;
  72. uint8_t status;
  73. uint8_t control;
  74. qemu_irq irq;
  75. int irq_pending;
  76. CharBackend chr;
  77. int hw_driver;
  78. int epp_timeout;
  79. uint32_t last_read_offset; /* For debugging */
  80. /* Memory-mapped interface */
  81. int it_shift;
  82. PortioList portio_list;
  83. } ParallelState;
  84. #define TYPE_ISA_PARALLEL "isa-parallel"
  85. #define ISA_PARALLEL(obj) \
  86. OBJECT_CHECK(ISAParallelState, (obj), TYPE_ISA_PARALLEL)
  87. typedef struct ISAParallelState {
  88. ISADevice parent_obj;
  89. uint32_t index;
  90. uint32_t iobase;
  91. uint32_t isairq;
  92. ParallelState state;
  93. } ISAParallelState;
  94. static void parallel_update_irq(ParallelState *s)
  95. {
  96. if (s->irq_pending)
  97. qemu_irq_raise(s->irq);
  98. else
  99. qemu_irq_lower(s->irq);
  100. }
  101. static void
  102. parallel_ioport_write_sw(void *opaque, uint32_t addr, uint32_t val)
  103. {
  104. ParallelState *s = opaque;
  105. addr &= 7;
  106. trace_parallel_ioport_write("SW", addr, val);
  107. switch(addr) {
  108. case PARA_REG_DATA:
  109. s->dataw = val;
  110. parallel_update_irq(s);
  111. break;
  112. case PARA_REG_CTR:
  113. val |= 0xc0;
  114. if ((val & PARA_CTR_INIT) == 0 ) {
  115. s->status = PARA_STS_BUSY;
  116. s->status |= PARA_STS_ACK;
  117. s->status |= PARA_STS_ONLINE;
  118. s->status |= PARA_STS_ERROR;
  119. }
  120. else if (val & PARA_CTR_SELECT) {
  121. if (val & PARA_CTR_STROBE) {
  122. s->status &= ~PARA_STS_BUSY;
  123. if ((s->control & PARA_CTR_STROBE) == 0)
  124. /* XXX this blocks entire thread. Rewrite to use
  125. * qemu_chr_fe_write and background I/O callbacks */
  126. qemu_chr_fe_write_all(&s->chr, &s->dataw, 1);
  127. } else {
  128. if (s->control & PARA_CTR_INTEN) {
  129. s->irq_pending = 1;
  130. }
  131. }
  132. }
  133. parallel_update_irq(s);
  134. s->control = val;
  135. break;
  136. }
  137. }
  138. static void parallel_ioport_write_hw(void *opaque, uint32_t addr, uint32_t val)
  139. {
  140. ParallelState *s = opaque;
  141. uint8_t parm = val;
  142. int dir;
  143. /* Sometimes programs do several writes for timing purposes on old
  144. HW. Take care not to waste time on writes that do nothing. */
  145. s->last_read_offset = ~0U;
  146. addr &= 7;
  147. trace_parallel_ioport_write("HW", addr, val);
  148. switch(addr) {
  149. case PARA_REG_DATA:
  150. if (s->dataw == val)
  151. return;
  152. pdebug("wd%02x\n", val);
  153. qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_WRITE_DATA, &parm);
  154. s->dataw = val;
  155. break;
  156. case PARA_REG_STS:
  157. pdebug("ws%02x\n", val);
  158. if (val & PARA_STS_TMOUT)
  159. s->epp_timeout = 0;
  160. break;
  161. case PARA_REG_CTR:
  162. val |= 0xc0;
  163. if (s->control == val)
  164. return;
  165. pdebug("wc%02x\n", val);
  166. if ((val & PARA_CTR_DIR) != (s->control & PARA_CTR_DIR)) {
  167. if (val & PARA_CTR_DIR) {
  168. dir = 1;
  169. } else {
  170. dir = 0;
  171. }
  172. qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_DATA_DIR, &dir);
  173. parm &= ~PARA_CTR_DIR;
  174. }
  175. qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_WRITE_CONTROL, &parm);
  176. s->control = val;
  177. break;
  178. case PARA_REG_EPP_ADDR:
  179. if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT)
  180. /* Controls not correct for EPP address cycle, so do nothing */
  181. pdebug("wa%02x s\n", val);
  182. else {
  183. struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 };
  184. if (qemu_chr_fe_ioctl(&s->chr,
  185. CHR_IOCTL_PP_EPP_WRITE_ADDR, &ioarg)) {
  186. s->epp_timeout = 1;
  187. pdebug("wa%02x t\n", val);
  188. }
  189. else
  190. pdebug("wa%02x\n", val);
  191. }
  192. break;
  193. case PARA_REG_EPP_DATA:
  194. if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT)
  195. /* Controls not correct for EPP data cycle, so do nothing */
  196. pdebug("we%02x s\n", val);
  197. else {
  198. struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 };
  199. if (qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg)) {
  200. s->epp_timeout = 1;
  201. pdebug("we%02x t\n", val);
  202. }
  203. else
  204. pdebug("we%02x\n", val);
  205. }
  206. break;
  207. }
  208. }
  209. static void
  210. parallel_ioport_eppdata_write_hw2(void *opaque, uint32_t addr, uint32_t val)
  211. {
  212. ParallelState *s = opaque;
  213. uint16_t eppdata = cpu_to_le16(val);
  214. int err;
  215. struct ParallelIOArg ioarg = {
  216. .buffer = &eppdata, .count = sizeof(eppdata)
  217. };
  218. trace_parallel_ioport_write("EPP", addr, val);
  219. if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT) {
  220. /* Controls not correct for EPP data cycle, so do nothing */
  221. pdebug("we%04x s\n", val);
  222. return;
  223. }
  224. err = qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
  225. if (err) {
  226. s->epp_timeout = 1;
  227. pdebug("we%04x t\n", val);
  228. }
  229. else
  230. pdebug("we%04x\n", val);
  231. }
  232. static void
  233. parallel_ioport_eppdata_write_hw4(void *opaque, uint32_t addr, uint32_t val)
  234. {
  235. ParallelState *s = opaque;
  236. uint32_t eppdata = cpu_to_le32(val);
  237. int err;
  238. struct ParallelIOArg ioarg = {
  239. .buffer = &eppdata, .count = sizeof(eppdata)
  240. };
  241. trace_parallel_ioport_write("EPP", addr, val);
  242. if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT) {
  243. /* Controls not correct for EPP data cycle, so do nothing */
  244. pdebug("we%08x s\n", val);
  245. return;
  246. }
  247. err = qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
  248. if (err) {
  249. s->epp_timeout = 1;
  250. pdebug("we%08x t\n", val);
  251. }
  252. else
  253. pdebug("we%08x\n", val);
  254. }
  255. static uint32_t parallel_ioport_read_sw(void *opaque, uint32_t addr)
  256. {
  257. ParallelState *s = opaque;
  258. uint32_t ret = 0xff;
  259. addr &= 7;
  260. switch(addr) {
  261. case PARA_REG_DATA:
  262. if (s->control & PARA_CTR_DIR)
  263. ret = s->datar;
  264. else
  265. ret = s->dataw;
  266. break;
  267. case PARA_REG_STS:
  268. ret = s->status;
  269. s->irq_pending = 0;
  270. if ((s->status & PARA_STS_BUSY) == 0 && (s->control & PARA_CTR_STROBE) == 0) {
  271. /* XXX Fixme: wait 5 microseconds */
  272. if (s->status & PARA_STS_ACK)
  273. s->status &= ~PARA_STS_ACK;
  274. else {
  275. /* XXX Fixme: wait 5 microseconds */
  276. s->status |= PARA_STS_ACK;
  277. s->status |= PARA_STS_BUSY;
  278. }
  279. }
  280. parallel_update_irq(s);
  281. break;
  282. case PARA_REG_CTR:
  283. ret = s->control;
  284. break;
  285. }
  286. trace_parallel_ioport_read("SW", addr, ret);
  287. return ret;
  288. }
  289. static uint32_t parallel_ioport_read_hw(void *opaque, uint32_t addr)
  290. {
  291. ParallelState *s = opaque;
  292. uint8_t ret = 0xff;
  293. addr &= 7;
  294. switch(addr) {
  295. case PARA_REG_DATA:
  296. qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_READ_DATA, &ret);
  297. if (s->last_read_offset != addr || s->datar != ret)
  298. pdebug("rd%02x\n", ret);
  299. s->datar = ret;
  300. break;
  301. case PARA_REG_STS:
  302. qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_READ_STATUS, &ret);
  303. ret &= ~PARA_STS_TMOUT;
  304. if (s->epp_timeout)
  305. ret |= PARA_STS_TMOUT;
  306. if (s->last_read_offset != addr || s->status != ret)
  307. pdebug("rs%02x\n", ret);
  308. s->status = ret;
  309. break;
  310. case PARA_REG_CTR:
  311. /* s->control has some bits fixed to 1. It is zero only when
  312. it has not been yet written to. */
  313. if (s->control == 0) {
  314. qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_READ_CONTROL, &ret);
  315. if (s->last_read_offset != addr)
  316. pdebug("rc%02x\n", ret);
  317. s->control = ret;
  318. }
  319. else {
  320. ret = s->control;
  321. if (s->last_read_offset != addr)
  322. pdebug("rc%02x\n", ret);
  323. }
  324. break;
  325. case PARA_REG_EPP_ADDR:
  326. if ((s->control & (PARA_CTR_DIR | PARA_CTR_SIGNAL)) !=
  327. (PARA_CTR_DIR | PARA_CTR_INIT))
  328. /* Controls not correct for EPP addr cycle, so do nothing */
  329. pdebug("ra%02x s\n", ret);
  330. else {
  331. struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 };
  332. if (qemu_chr_fe_ioctl(&s->chr,
  333. CHR_IOCTL_PP_EPP_READ_ADDR, &ioarg)) {
  334. s->epp_timeout = 1;
  335. pdebug("ra%02x t\n", ret);
  336. }
  337. else
  338. pdebug("ra%02x\n", ret);
  339. }
  340. break;
  341. case PARA_REG_EPP_DATA:
  342. if ((s->control & (PARA_CTR_DIR | PARA_CTR_SIGNAL)) !=
  343. (PARA_CTR_DIR | PARA_CTR_INIT))
  344. /* Controls not correct for EPP data cycle, so do nothing */
  345. pdebug("re%02x s\n", ret);
  346. else {
  347. struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 };
  348. if (qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg)) {
  349. s->epp_timeout = 1;
  350. pdebug("re%02x t\n", ret);
  351. }
  352. else
  353. pdebug("re%02x\n", ret);
  354. }
  355. break;
  356. }
  357. trace_parallel_ioport_read("HW", addr, ret);
  358. s->last_read_offset = addr;
  359. return ret;
  360. }
  361. static uint32_t
  362. parallel_ioport_eppdata_read_hw2(void *opaque, uint32_t addr)
  363. {
  364. ParallelState *s = opaque;
  365. uint32_t ret;
  366. uint16_t eppdata = ~0;
  367. int err;
  368. struct ParallelIOArg ioarg = {
  369. .buffer = &eppdata, .count = sizeof(eppdata)
  370. };
  371. if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT)) {
  372. /* Controls not correct for EPP data cycle, so do nothing */
  373. pdebug("re%04x s\n", eppdata);
  374. return eppdata;
  375. }
  376. err = qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
  377. ret = le16_to_cpu(eppdata);
  378. if (err) {
  379. s->epp_timeout = 1;
  380. pdebug("re%04x t\n", ret);
  381. }
  382. else
  383. pdebug("re%04x\n", ret);
  384. trace_parallel_ioport_read("EPP", addr, ret);
  385. return ret;
  386. }
  387. static uint32_t
  388. parallel_ioport_eppdata_read_hw4(void *opaque, uint32_t addr)
  389. {
  390. ParallelState *s = opaque;
  391. uint32_t ret;
  392. uint32_t eppdata = ~0U;
  393. int err;
  394. struct ParallelIOArg ioarg = {
  395. .buffer = &eppdata, .count = sizeof(eppdata)
  396. };
  397. if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT)) {
  398. /* Controls not correct for EPP data cycle, so do nothing */
  399. pdebug("re%08x s\n", eppdata);
  400. return eppdata;
  401. }
  402. err = qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
  403. ret = le32_to_cpu(eppdata);
  404. if (err) {
  405. s->epp_timeout = 1;
  406. pdebug("re%08x t\n", ret);
  407. }
  408. else
  409. pdebug("re%08x\n", ret);
  410. trace_parallel_ioport_read("EPP", addr, ret);
  411. return ret;
  412. }
  413. static void parallel_ioport_ecp_write(void *opaque, uint32_t addr, uint32_t val)
  414. {
  415. trace_parallel_ioport_write("ECP", addr & 7, val);
  416. pdebug("wecp%d=%02x\n", addr & 7, val);
  417. }
  418. static uint32_t parallel_ioport_ecp_read(void *opaque, uint32_t addr)
  419. {
  420. uint8_t ret = 0xff;
  421. trace_parallel_ioport_read("ECP", addr & 7, ret);
  422. pdebug("recp%d:%02x\n", addr & 7, ret);
  423. return ret;
  424. }
  425. static void parallel_reset(void *opaque)
  426. {
  427. ParallelState *s = opaque;
  428. s->datar = ~0;
  429. s->dataw = ~0;
  430. s->status = PARA_STS_BUSY;
  431. s->status |= PARA_STS_ACK;
  432. s->status |= PARA_STS_ONLINE;
  433. s->status |= PARA_STS_ERROR;
  434. s->status |= PARA_STS_TMOUT;
  435. s->control = PARA_CTR_SELECT;
  436. s->control |= PARA_CTR_INIT;
  437. s->control |= 0xc0;
  438. s->irq_pending = 0;
  439. s->hw_driver = 0;
  440. s->epp_timeout = 0;
  441. s->last_read_offset = ~0U;
  442. }
  443. static const int isa_parallel_io[MAX_PARALLEL_PORTS] = { 0x378, 0x278, 0x3bc };
  444. static const MemoryRegionPortio isa_parallel_portio_hw_list[] = {
  445. { 0, 8, 1,
  446. .read = parallel_ioport_read_hw,
  447. .write = parallel_ioport_write_hw },
  448. { 4, 1, 2,
  449. .read = parallel_ioport_eppdata_read_hw2,
  450. .write = parallel_ioport_eppdata_write_hw2 },
  451. { 4, 1, 4,
  452. .read = parallel_ioport_eppdata_read_hw4,
  453. .write = parallel_ioport_eppdata_write_hw4 },
  454. { 0x400, 8, 1,
  455. .read = parallel_ioport_ecp_read,
  456. .write = parallel_ioport_ecp_write },
  457. PORTIO_END_OF_LIST(),
  458. };
  459. static const MemoryRegionPortio isa_parallel_portio_sw_list[] = {
  460. { 0, 8, 1,
  461. .read = parallel_ioport_read_sw,
  462. .write = parallel_ioport_write_sw },
  463. PORTIO_END_OF_LIST(),
  464. };
  465. static const VMStateDescription vmstate_parallel_isa = {
  466. .name = "parallel_isa",
  467. .version_id = 1,
  468. .minimum_version_id = 1,
  469. .fields = (VMStateField[]) {
  470. VMSTATE_UINT8(state.dataw, ISAParallelState),
  471. VMSTATE_UINT8(state.datar, ISAParallelState),
  472. VMSTATE_UINT8(state.status, ISAParallelState),
  473. VMSTATE_UINT8(state.control, ISAParallelState),
  474. VMSTATE_INT32(state.irq_pending, ISAParallelState),
  475. VMSTATE_INT32(state.epp_timeout, ISAParallelState),
  476. VMSTATE_END_OF_LIST()
  477. }
  478. };
  479. static int parallel_can_receive(void *opaque)
  480. {
  481. return 1;
  482. }
  483. static void parallel_isa_realizefn(DeviceState *dev, Error **errp)
  484. {
  485. static int index;
  486. ISADevice *isadev = ISA_DEVICE(dev);
  487. ISAParallelState *isa = ISA_PARALLEL(dev);
  488. ParallelState *s = &isa->state;
  489. int base;
  490. uint8_t dummy;
  491. if (!qemu_chr_fe_backend_connected(&s->chr)) {
  492. error_setg(errp, "Can't create parallel device, empty char device");
  493. return;
  494. }
  495. if (isa->index == -1) {
  496. isa->index = index;
  497. }
  498. if (isa->index >= MAX_PARALLEL_PORTS) {
  499. error_setg(errp, "Max. supported number of parallel ports is %d.",
  500. MAX_PARALLEL_PORTS);
  501. return;
  502. }
  503. if (isa->iobase == -1) {
  504. isa->iobase = isa_parallel_io[isa->index];
  505. }
  506. index++;
  507. base = isa->iobase;
  508. isa_init_irq(isadev, &s->irq, isa->isairq);
  509. qemu_register_reset(parallel_reset, s);
  510. qemu_chr_fe_set_handlers(&s->chr, parallel_can_receive, NULL,
  511. NULL, NULL, s, NULL, true);
  512. if (qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) {
  513. s->hw_driver = 1;
  514. s->status = dummy;
  515. }
  516. isa_register_portio_list(isadev, &s->portio_list, base,
  517. (s->hw_driver
  518. ? &isa_parallel_portio_hw_list[0]
  519. : &isa_parallel_portio_sw_list[0]),
  520. s, "parallel");
  521. }
  522. /* Memory mapped interface */
  523. static uint64_t parallel_mm_readfn(void *opaque, hwaddr addr, unsigned size)
  524. {
  525. ParallelState *s = opaque;
  526. return parallel_ioport_read_sw(s, addr >> s->it_shift) &
  527. MAKE_64BIT_MASK(0, size * 8);
  528. }
  529. static void parallel_mm_writefn(void *opaque, hwaddr addr,
  530. uint64_t value, unsigned size)
  531. {
  532. ParallelState *s = opaque;
  533. parallel_ioport_write_sw(s, addr >> s->it_shift,
  534. value & MAKE_64BIT_MASK(0, size * 8));
  535. }
  536. static const MemoryRegionOps parallel_mm_ops = {
  537. .read = parallel_mm_readfn,
  538. .write = parallel_mm_writefn,
  539. .valid.min_access_size = 1,
  540. .valid.max_access_size = 4,
  541. .endianness = DEVICE_NATIVE_ENDIAN,
  542. };
  543. /* If fd is zero, it means that the parallel device uses the console */
  544. bool parallel_mm_init(MemoryRegion *address_space,
  545. hwaddr base, int it_shift, qemu_irq irq,
  546. Chardev *chr)
  547. {
  548. ParallelState *s;
  549. s = g_malloc0(sizeof(ParallelState));
  550. s->irq = irq;
  551. qemu_chr_fe_init(&s->chr, chr, &error_abort);
  552. s->it_shift = it_shift;
  553. qemu_register_reset(parallel_reset, s);
  554. memory_region_init_io(&s->iomem, NULL, &parallel_mm_ops, s,
  555. "parallel", 8 << it_shift);
  556. memory_region_add_subregion(address_space, base, &s->iomem);
  557. return true;
  558. }
  559. static Property parallel_isa_properties[] = {
  560. DEFINE_PROP_UINT32("index", ISAParallelState, index, -1),
  561. DEFINE_PROP_UINT32("iobase", ISAParallelState, iobase, -1),
  562. DEFINE_PROP_UINT32("irq", ISAParallelState, isairq, 7),
  563. DEFINE_PROP_CHR("chardev", ISAParallelState, state.chr),
  564. DEFINE_PROP_END_OF_LIST(),
  565. };
  566. static void parallel_isa_class_initfn(ObjectClass *klass, void *data)
  567. {
  568. DeviceClass *dc = DEVICE_CLASS(klass);
  569. dc->realize = parallel_isa_realizefn;
  570. dc->vmsd = &vmstate_parallel_isa;
  571. dc->props = parallel_isa_properties;
  572. set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
  573. }
  574. static const TypeInfo parallel_isa_info = {
  575. .name = TYPE_ISA_PARALLEL,
  576. .parent = TYPE_ISA_DEVICE,
  577. .instance_size = sizeof(ISAParallelState),
  578. .class_init = parallel_isa_class_initfn,
  579. };
  580. static void parallel_register_types(void)
  581. {
  582. type_register_static(&parallel_isa_info);
  583. }
  584. type_init(parallel_register_types)