49
46
struct etrax_serial
55
/* This pending thing is a hack. */
58
/* Control registers. */
52
/* This pending thing is a hack. */
55
/* Control registers. */
62
59
static void ser_update_irq(struct etrax_serial *s)
64
s->regs[R_INTR] &= ~(s->regs[RW_ACK_INTR]);
65
s->regs[R_MASKED_INTR] = s->regs[R_INTR] & s->regs[RW_INTR_MASK];
61
s->regs[R_INTR] &= ~(s->regs[RW_ACK_INTR]);
62
s->regs[R_MASKED_INTR] = s->regs[R_INTR] & s->regs[RW_INTR_MASK];
67
qemu_set_irq(s->irq[0], !!s->regs[R_MASKED_INTR]);
68
s->regs[RW_ACK_INTR] = 0;
64
qemu_set_irq(s->irq, !!s->regs[R_MASKED_INTR]);
65
s->regs[RW_ACK_INTR] = 0;
71
68
static uint32_t ser_readl (void *opaque, target_phys_addr_t addr)
73
struct etrax_serial *s = opaque;
74
D(CPUState *env = s->env);
70
struct etrax_serial *s = opaque;
71
D(CPUState *env = s->env);
81
r = s->regs[RS_STAT_DIN];
85
/* Read side-effect: clear dav. */
86
s->regs[addr] &= ~(1 << STAT_DAV);
90
D(printf ("%s %x=%x\n", __func__, addr, r));
78
r = s->regs[RS_STAT_DIN];
82
/* Read side-effect: clear dav. */
83
s->regs[addr] &= ~(1 << STAT_DAV);
87
D(printf ("%s %x=%x\n", __func__, addr, r));
97
94
ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
99
struct etrax_serial *s = opaque;
100
unsigned char ch = value;
101
D(CPUState *env = s->env);
96
struct etrax_serial *s = opaque;
97
unsigned char ch = value;
98
D(CPUState *env = s->env);
103
D(printf ("%s %x %x\n", __func__, addr, value));
108
qemu_chr_write(s->chr, &ch, 1);
109
s->regs[R_INTR] |= 1;
111
s->regs[addr] = value;
114
s->regs[addr] = value;
115
if (s->pending_tx && (s->regs[addr] & 1)) {
116
s->regs[R_INTR] |= 1;
122
s->regs[addr] = value;
100
D(printf ("%s %x %x\n", __func__, addr, value));
105
qemu_chr_write(s->chr, &ch, 1);
106
s->regs[R_INTR] |= 1;
108
s->regs[addr] = value;
111
s->regs[addr] = value;
112
if (s->pending_tx && (s->regs[addr] & 1)) {
113
s->regs[R_INTR] |= 1;
119
s->regs[addr] = value;
128
125
static CPUReadMemoryFunc *ser_read[] = {
133
130
static CPUWriteMemoryFunc *ser_write[] = {
138
135
static void serial_receive(void *opaque, const uint8_t *buf, int size)
140
struct etrax_serial *s = opaque;
137
struct etrax_serial *s = opaque;
142
s->regs[R_INTR] |= 8;
143
s->regs[RS_STAT_DIN] &= ~0xff;
144
s->regs[RS_STAT_DIN] |= (buf[0] & 0xff);
145
s->regs[RS_STAT_DIN] |= (1 << STAT_DAV); /* dav. */
139
s->regs[R_INTR] |= 8;
140
s->regs[RS_STAT_DIN] &= ~0xff;
141
s->regs[RS_STAT_DIN] |= (buf[0] & 0xff);
142
s->regs[RS_STAT_DIN] |= (1 << STAT_DAV); /* dav. */
149
146
static int serial_can_receive(void *opaque)
151
struct etrax_serial *s = opaque;
154
/* Is the receiver enabled? */
155
r = s->regs[RW_REC_CTRL] & 1;
157
/* Pending rx data? */
158
r |= !(s->regs[R_INTR] & 8);
148
struct etrax_serial *s = opaque;
151
/* Is the receiver enabled? */
152
r = s->regs[RW_REC_CTRL] & 1;
154
/* Pending rx data? */
155
r |= !(s->regs[R_INTR] & 8);
162
159
static void serial_event(void *opaque, int event)
167
void etraxfs_ser_init(CPUState *env, qemu_irq *irq, CharDriverState *chr,
168
target_phys_addr_t base)
170
struct etrax_serial *s;
173
s = qemu_mallocz(sizeof *s);
179
/* transmitter begins ready and idle. */
180
s->regs[RS_STAT_DIN] |= (1 << STAT_TR_RDY);
181
s->regs[RS_STAT_DIN] |= (1 << STAT_TR_IDLE);
183
qemu_chr_add_handlers(chr, serial_can_receive, serial_receive,
186
ser_regs = cpu_register_io_memory(0, ser_read, ser_write, s);
187
cpu_register_physical_memory (base, R_MAX * 4, ser_regs);
164
static void etraxfs_ser_init(SysBusDevice *dev)
166
struct etrax_serial *s = FROM_SYSBUS(typeof (*s), dev);
169
/* transmitter begins ready and idle. */
170
s->regs[RS_STAT_DIN] |= (1 << STAT_TR_RDY);
171
s->regs[RS_STAT_DIN] |= (1 << STAT_TR_IDLE);
173
sysbus_init_irq(dev, &s->irq);
174
ser_regs = cpu_register_io_memory(0, ser_read, ser_write, s);
175
sysbus_init_mmio(dev, R_MAX * 4, ser_regs);
176
s->chr = qdev_init_chardev(&dev->qdev);
178
qemu_chr_add_handlers(s->chr,
179
serial_can_receive, serial_receive,
183
static void etraxfs_serial_register(void)
185
sysbus_register_dev("etraxfs,serial", sizeof (struct etrax_serial),
189
device_init(etraxfs_serial_register)