Lines Matching +full:data +full:- +full:channel
2 * QEMU GE IP-Octal 232 IndustryPack emulation
14 #include "hw/qdev-properties.h"
15 #include "hw/qdev-properties-system.h"
19 #include "chardev/char-fe.h"
31 #define DPRINTF(fmt, ...) DPRINTF2("IP-Octal: " fmt, ## __VA_ARGS__)
35 /* The IP-Octal has 8 channels (a-h)
36 divided into 4 blocks (A-D) */
171 /* data[10] is 0x0C, not 0x0B as the doc says */
182 SCC2698Block *blk0 = &dev->blk[block]; in update_irq()
183 SCC2698Block *blk1 = &dev->blk[block^1]; in update_irq()
186 if ((blk0->isr & blk0->imr) || (blk1->isr & blk1->imr)) { in update_irq()
187 qemu_irq_raise(&idev->irq[intno]); in update_irq()
189 qemu_irq_lower(&idev->irq[intno]); in update_irq()
193 static void write_cr(IPOctalState *dev, unsigned channel, uint8_t val) in write_cr() argument
195 SCC2698Channel *ch = &dev->ch[channel]; in write_cr()
196 SCC2698Block *blk = &dev->blk[channel / 2]; in write_cr()
198 DPRINTF("Write CR%c %u: ", channel + 'a', val); in write_cr()
203 ch->rx_enabled = true; in write_cr()
207 ch->rx_enabled = false; in write_cr()
211 ch->sr |= SR_TXRDY | SR_TXEMT; in write_cr()
212 blk->isr |= ISR_TXRDY(channel); in write_cr()
216 ch->sr &= ~(SR_TXRDY | SR_TXEMT); in write_cr()
217 blk->isr &= ~ISR_TXRDY(channel); in write_cr()
229 ch->mr_idx = 0; in write_cr()
233 ch->rx_enabled = false; in write_cr()
234 ch->rx_pending = 0; in write_cr()
235 ch->sr &= ~SR_RXRDY; in write_cr()
236 blk->isr &= ~ISR_RXRDY(channel); in write_cr()
240 ch->sr &= ~(SR_TXRDY | SR_TXEMT); in write_cr()
241 blk->isr &= ~ISR_TXRDY(channel); in write_cr()
245 ch->sr &= ~(SR_OVERRUN | SR_PARITY | SR_FRAMING | SR_BREAK); in write_cr()
249 blk->isr &= ~(ISR_BREAKA | ISR_BREAKB); in write_cr()
262 /* addr[7:6]: block (A-D) in io_read()
263 addr[7:5]: channel (a-h) in io_read()
266 unsigned channel = addr >> 4; in io_read() local
267 /* Big endian, accessed using 8-bit bytes at odd locations */ in io_read()
269 SCC2698Channel *ch = &dev->ch[channel]; in io_read()
270 SCC2698Block *blk = &dev->blk[block]; in io_read()
271 uint8_t old_isr = blk->isr; in io_read()
277 ret = ch->mr[ch->mr_idx]; in io_read()
278 DPRINTF("Read MR%u%c: 0x%x\n", ch->mr_idx + 1, channel + 'a', ret); in io_read()
279 ch->mr_idx = 1; in io_read()
284 ret = ch->sr; in io_read()
285 DPRINTF("Read SR%c: 0x%x\n", channel + 'a', ret); in io_read()
290 ret = ch->rhr[ch->rhr_idx]; in io_read()
291 if (ch->rx_pending > 0) { in io_read()
292 ch->rx_pending--; in io_read()
293 if (ch->rx_pending == 0) { in io_read()
294 ch->sr &= ~SR_RXRDY; in io_read()
295 blk->isr &= ~ISR_RXRDY(channel); in io_read()
296 qemu_chr_fe_accept_input(&ch->dev); in io_read()
298 ch->rhr_idx = (ch->rhr_idx + 1) % RX_FIFO_SIZE; in io_read()
300 if (ch->sr & SR_BREAK) { in io_read()
301 ch->sr &= ~SR_BREAK; in io_read()
302 blk->isr |= ISR_BREAK(channel); in io_read()
305 DPRINTF("Read RHR%c (0x%x)\n", channel + 'a', ret); in io_read()
309 ret = blk->isr; in io_read()
317 if (old_isr != blk->isr) { in io_read()
328 /* addr[7:6]: block (A-D) in io_write()
329 addr[7:5]: channel (a-h) in io_write()
332 unsigned channel = addr >> 4; in io_write() local
333 /* Big endian, accessed using 8-bit bytes at odd locations */ in io_write()
335 SCC2698Channel *ch = &dev->ch[channel]; in io_write()
336 SCC2698Block *blk = &dev->blk[block]; in io_write()
337 uint8_t old_isr = blk->isr; in io_write()
338 uint8_t old_imr = blk->imr; in io_write()
344 ch->mr[ch->mr_idx] = reg; in io_write()
345 DPRINTF("Write MR%u%c 0x%x\n", ch->mr_idx + 1, channel + 'a', reg); in io_write()
346 ch->mr_idx = 1; in io_write()
352 DPRINTF("Write CSR%c: 0x%x\n", channel + 'a', reg); in io_write()
357 write_cr(dev, channel, reg); in io_write()
362 if (ch->sr & SR_TXRDY) { in io_write()
364 DPRINTF("Write THR%c (0x%x)\n", channel + 'a', reg); in io_write()
367 qemu_chr_fe_write_all(&ch->dev, &thr, 1); in io_write()
369 DPRINTF("Write THR%c (0x%x), Tx disabled\n", channel + 'a', reg); in io_write()
380 blk->imr = reg; in io_write()
392 if (old_isr != blk->isr || old_imr != blk->imr) { in io_write()
400 unsigned pos = addr / 2; /* The ID PROM data is stored every other byte */ in id_read()
405 DPRINTF("Attempt to read unavailable PROM data at 0x%x\n", addr); in id_read()
416 dev->irq_vector = val; /* Undocumented, but the hw works like that */ in id_write()
432 return dev->irq_vector; in int_read()
463 dev->irq_vector = val; in mem_write8()
472 int available_bytes = RX_FIFO_SIZE - ch->rx_pending; in hostdev_can_receive()
473 return ch->rx_enabled ? available_bytes : 0; in hostdev_can_receive()
479 IPOctalState *dev = ch->ipoctal; in hostdev_receive()
480 unsigned pos = ch->rhr_idx + ch->rx_pending; in hostdev_receive()
483 assert(size + ch->rx_pending <= RX_FIFO_SIZE); in hostdev_receive()
485 /* Copy data to the RxFIFO */ in hostdev_receive()
488 ch->rhr[pos++] = buf[i]; in hostdev_receive()
491 ch->rx_pending += size; in hostdev_receive()
494 if (!(ch->sr & SR_RXRDY)) { in hostdev_receive()
495 unsigned block, channel = 0; in hostdev_receive() local
496 /* Find channel number to update the ISR register */ in hostdev_receive()
497 while (&dev->ch[channel] != ch) { in hostdev_receive()
498 channel++; in hostdev_receive()
500 block = channel / 2; in hostdev_receive()
501 dev->blk[block].isr |= ISR_RXRDY(channel); in hostdev_receive()
502 ch->sr |= SR_RXRDY; in hostdev_receive()
512 DPRINTF("Device %s opened\n", ch->dev->label); in hostdev_event()
516 DPRINTF("Device %s received break\n", ch->dev->label); in hostdev_event()
518 if (!(ch->sr & SR_BREAK)) { in hostdev_event()
519 IPOctalState *dev = ch->ipoctal; in hostdev_event()
520 unsigned block, channel = 0; in hostdev_event() local
522 while (&dev->ch[channel] != ch) { in hostdev_event()
523 channel++; in hostdev_event()
525 block = channel / 2; in hostdev_event()
527 ch->sr |= SR_BREAK; in hostdev_event()
528 dev->blk[block].isr |= ISR_BREAK(channel); in hostdev_event()
536 DPRINTF("Device %s received event %d\n", ch->dev->label, event); in hostdev_event()
546 SCC2698Channel *ch = &s->ch[i]; in ipoctal_realize()
547 ch->ipoctal = s; in ipoctal_realize()
549 /* Redirect IP-Octal channels to host character devices */ in ipoctal_realize()
550 if (qemu_chr_fe_backend_connected(&ch->dev)) { in ipoctal_realize()
551 qemu_chr_fe_set_handlers(&ch->dev, hostdev_can_receive, in ipoctal_realize()
554 DPRINTF("Redirecting channel %u to %s\n", i, ch->dev->label); in ipoctal_realize()
556 DPRINTF("Could not redirect channel %u, no chardev set\n", i); in ipoctal_realize()
572 static void ipoctal_class_init(ObjectClass *klass, const void *data) in ipoctal_class_init() argument
577 ic->realize = ipoctal_realize; in ipoctal_class_init()
578 ic->io_read = io_read; in ipoctal_class_init()
579 ic->io_write = io_write; in ipoctal_class_init()
580 ic->id_read = id_read; in ipoctal_class_init()
581 ic->id_write = id_write; in ipoctal_class_init()
582 ic->int_read = int_read; in ipoctal_class_init()
583 ic->int_write = int_write; in ipoctal_class_init()
584 ic->mem_read16 = mem_read16; in ipoctal_class_init()
585 ic->mem_write16 = mem_write16; in ipoctal_class_init()
586 ic->mem_read8 = mem_read8; in ipoctal_class_init()
587 ic->mem_write8 = mem_write8; in ipoctal_class_init()
589 set_bit(DEVICE_CATEGORY_INPUT, dc->categories); in ipoctal_class_init()
590 dc->desc = "GE IP-Octal 232 8-channel RS-232 IndustryPack"; in ipoctal_class_init()
592 dc->vmsd = &vmstate_ipoctal; in ipoctal_class_init()