|
|
1.1 root 1: /*
2: * QEMU ETRAX System Emulator
3: *
4: * Copyright (c) 2007 Edgar E. Iglesias, Axis Communications AB.
5: *
6: * Permission is hereby granted, free of charge, to any person obtaining a copy
7: * of this software and associated documentation files (the "Software"), to deal
8: * in the Software without restriction, including without limitation the rights
9: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10: * copies of the Software, and to permit persons to whom the Software is
11: * furnished to do so, subject to the following conditions:
12: *
13: * The above copyright notice and this permission notice shall be included in
14: * all copies or substantial portions of the Software.
15: *
16: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22: * THE SOFTWARE.
23: */
24:
1.1.1.3 root 25: #include "sysbus.h"
1.1.1.2 root 26: #include "qemu-char.h"
1.1 root 27:
1.1.1.2 root 28: #define D(x)
1.1 root 29:
1.1.1.3 root 30: #define RW_TR_CTRL (0x00 / 4)
31: #define RW_TR_DMA_EN (0x04 / 4)
32: #define RW_REC_CTRL (0x08 / 4)
33: #define RW_DOUT (0x1c / 4)
34: #define RS_STAT_DIN (0x20 / 4)
35: #define R_STAT_DIN (0x24 / 4)
36: #define RW_INTR_MASK (0x2c / 4)
37: #define RW_ACK_INTR (0x30 / 4)
38: #define R_INTR (0x34 / 4)
39: #define R_MASKED_INTR (0x38 / 4)
40: #define R_MAX (0x3c / 4)
1.1.1.2 root 41:
42: #define STAT_DAV 16
43: #define STAT_TR_IDLE 22
44: #define STAT_TR_RDY 24
45:
1.1.1.3 root 46: struct etrax_serial
1.1.1.2 root 47: {
1.1.1.3 root 48: SysBusDevice busdev;
49: CharDriverState *chr;
50: qemu_irq irq;
1.1.1.2 root 51:
1.1.1.3 root 52: int pending_tx;
1.1.1.2 root 53:
1.1.1.5 root 54: uint8_t rx_fifo[16];
55: unsigned int rx_fifo_pos;
56: unsigned int rx_fifo_len;
57:
1.1.1.3 root 58: /* Control registers. */
59: uint32_t regs[R_MAX];
60: };
1.1.1.2 root 61:
1.1.1.3 root 62: static void ser_update_irq(struct etrax_serial *s)
1.1 root 63: {
1.1.1.3 root 64:
1.1.1.5 root 65: if (s->rx_fifo_len) {
66: s->regs[R_INTR] |= 8;
67: } else {
68: s->regs[R_INTR] &= ~8;
69: }
70:
71: s->regs[R_MASKED_INTR] = s->regs[R_INTR] & s->regs[RW_INTR_MASK];
1.1.1.3 root 72: qemu_set_irq(s->irq, !!s->regs[R_MASKED_INTR]);
1.1 root 73: }
74:
75: static uint32_t ser_readl (void *opaque, target_phys_addr_t addr)
76: {
1.1.1.3 root 77: struct etrax_serial *s = opaque;
78: D(CPUState *env = s->env);
79: uint32_t r = 0;
80:
81: addr >>= 2;
82: switch (addr)
83: {
84: case R_STAT_DIN:
1.1.1.5 root 85: r = s->rx_fifo[(s->rx_fifo_pos - s->rx_fifo_len) & 15];
86: if (s->rx_fifo_len) {
87: r |= 1 << STAT_DAV;
88: }
89: r |= 1 << STAT_TR_RDY;
90: r |= 1 << STAT_TR_IDLE;
1.1.1.3 root 91: break;
92: case RS_STAT_DIN:
1.1.1.5 root 93: r = s->rx_fifo[(s->rx_fifo_pos - s->rx_fifo_len) & 15];
94: if (s->rx_fifo_len) {
95: r |= 1 << STAT_DAV;
96: s->rx_fifo_len--;
97: }
98: r |= 1 << STAT_TR_RDY;
99: r |= 1 << STAT_TR_IDLE;
1.1.1.3 root 100: break;
101: default:
102: r = s->regs[addr];
1.1.1.5 root 103: D(printf ("%s " TARGET_FMT_plx "=%x\n", __func__, addr, r));
1.1.1.3 root 104: break;
105: }
106: return r;
1.1 root 107: }
108:
109: static void
110: ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
111: {
1.1.1.3 root 112: struct etrax_serial *s = opaque;
113: unsigned char ch = value;
114: D(CPUState *env = s->env);
115:
1.1.1.5 root 116: D(printf ("%s " TARGET_FMT_plx "=%x\n", __func__, addr, value));
1.1.1.3 root 117: addr >>= 2;
118: switch (addr)
119: {
120: case RW_DOUT:
121: qemu_chr_write(s->chr, &ch, 1);
1.1.1.5 root 122: s->regs[R_INTR] |= 3;
1.1.1.3 root 123: s->pending_tx = 1;
124: s->regs[addr] = value;
125: break;
126: case RW_ACK_INTR:
1.1.1.5 root 127: if (s->pending_tx) {
128: value &= ~1;
1.1.1.3 root 129: s->pending_tx = 0;
1.1.1.5 root 130: D(printf("fixedup value=%x r_intr=%x\n", value, s->regs[R_INTR]));
1.1.1.3 root 131: }
1.1.1.5 root 132: s->regs[addr] = value;
133: s->regs[R_INTR] &= ~value;
134: D(printf("r_intr=%x\n", s->regs[R_INTR]));
1.1.1.3 root 135: break;
136: default:
137: s->regs[addr] = value;
138: break;
139: }
140: ser_update_irq(s);
1.1 root 141: }
142:
1.1.1.4 root 143: static CPUReadMemoryFunc * const ser_read[] = {
1.1.1.3 root 144: NULL, NULL,
145: &ser_readl,
1.1 root 146: };
147:
1.1.1.4 root 148: static CPUWriteMemoryFunc * const ser_write[] = {
1.1.1.3 root 149: NULL, NULL,
150: &ser_writel,
1.1 root 151: };
152:
1.1.1.2 root 153: static void serial_receive(void *opaque, const uint8_t *buf, int size)
154: {
1.1.1.3 root 155: struct etrax_serial *s = opaque;
1.1.1.5 root 156: int i;
157:
158: /* Got a byte. */
159: if (s->rx_fifo_len >= 16) {
160: printf("WARNING: UART dropped char.\n");
161: return;
162: }
163:
164: for (i = 0; i < size; i++) {
165: s->rx_fifo[s->rx_fifo_pos] = buf[i];
166: s->rx_fifo_pos++;
167: s->rx_fifo_pos &= 15;
168: s->rx_fifo_len++;
169: }
1.1.1.2 root 170:
1.1.1.3 root 171: ser_update_irq(s);
1.1.1.2 root 172: }
173:
174: static int serial_can_receive(void *opaque)
1.1 root 175: {
1.1.1.3 root 176: struct etrax_serial *s = opaque;
177: int r;
1.1.1.2 root 178:
1.1.1.3 root 179: /* Is the receiver enabled? */
1.1.1.5 root 180: if (!(s->regs[RW_REC_CTRL] & (1 << 3))) {
181: return 0;
182: }
1.1.1.2 root 183:
1.1.1.5 root 184: r = sizeof(s->rx_fifo) - s->rx_fifo_len;
1.1.1.3 root 185: return r;
1.1.1.2 root 186: }
187:
188: static void serial_event(void *opaque, int event)
189: {
190:
191: }
192:
1.1.1.7 ! root 193: static void etraxfs_ser_reset(DeviceState *d)
1.1.1.2 root 194: {
1.1.1.7 ! root 195: struct etrax_serial *s = container_of(d, typeof(*s), busdev.qdev);
1.1.1.2 root 196:
1.1.1.3 root 197: /* transmitter begins ready and idle. */
198: s->regs[RS_STAT_DIN] |= (1 << STAT_TR_RDY);
199: s->regs[RS_STAT_DIN] |= (1 << STAT_TR_IDLE);
1.1.1.2 root 200:
1.1.1.7 ! root 201: s->regs[RW_REC_CTRL] = 0x10000;
! 202:
! 203: }
! 204:
! 205: static int etraxfs_ser_init(SysBusDevice *dev)
! 206: {
! 207: struct etrax_serial *s = FROM_SYSBUS(typeof (*s), dev);
! 208: int ser_regs;
! 209:
1.1.1.3 root 210: sysbus_init_irq(dev, &s->irq);
1.1.1.6 root 211: ser_regs = cpu_register_io_memory(ser_read, ser_write, s,
212: DEVICE_NATIVE_ENDIAN);
1.1.1.3 root 213: sysbus_init_mmio(dev, R_MAX * 4, ser_regs);
214: s->chr = qdev_init_chardev(&dev->qdev);
215: if (s->chr)
216: qemu_chr_add_handlers(s->chr,
217: serial_can_receive, serial_receive,
218: serial_event, s);
1.1.1.4 root 219: return 0;
1.1.1.3 root 220: }
1.1.1.2 root 221:
1.1.1.7 ! root 222: static SysBusDeviceInfo etraxfs_ser_info = {
! 223: .init = etraxfs_ser_init,
! 224: .qdev.name = "etraxfs,serial",
! 225: .qdev.size = sizeof(struct etrax_serial),
! 226: .qdev.reset = etraxfs_ser_reset,
! 227: };
! 228:
1.1.1.3 root 229: static void etraxfs_serial_register(void)
230: {
1.1.1.7 ! root 231: sysbus_register_withprop(&etraxfs_ser_info);
1.1 root 232: }
1.1.1.3 root 233:
234: device_init(etraxfs_serial_register)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.