4 * Copyright (c) 2009 Filip Navara
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
25 /* TODO: Channel mode, ICE pins, FIFO?, overrun, retransmission */
28 #include "qemu-char.h"
31 /* #define DEBUG_DBGU */
33 #define DBGU_SIZE 0x200
35 #define DBGU_CR 0x00 /* Control Register */
36 #define DBGU_MR 0x04 /* Mode Register */
37 #define DBGU_IER 0x08 /* Interrupt Enable Register */
38 #define DBGU_IDR 0x0c /* Interrupt Disable Register */
39 #define DBGU_IMR 0x10 /* Interrupt Mask Register */
40 #define DBGU_SR 0x14 /* Channel Status Register */
41 #define DBGU_RHR 0x18 /* Receiver Holding Register */
42 #define DBGU_THR 0x1c /* Transmitter Holding Register */
43 #define DBGU_BRGR 0x20 /* Baud Rate Generator Register */
44 #define DBGU_CIDR 0x40 /* Chip ID Register */
45 #define DBGU_EXID 0x44 /* Chip ID Extension Register */
46 #define DBGU_FNR 0x48 /* Force NTRST Register */
48 #define SR_RXRDY 0x01 /* Reciever Ready */
49 #define SR_TXRDY 0x02 /* Transmitter Ready */
50 #define SR_ENDRX 0x08 /* End of Receive Transfer */
51 #define SR_ENDTX 0x10 /* End of Transmit */
52 #define SR_OVRE 0x20 /* Overrun */
53 #define SR_FRAME 0x40 /* Framing Error */
54 #define SR_PARE 0x80 /* Parity Error */
55 #define SR_TXEMPTY 0x200 /* Transmitter Empty */
56 #define SR_TXBUFE 0x800 /* Transmission Buffer Empty */
57 #define SR_RXBUFF 0x1000 /* Receiver Buffer Full */
58 #define SR_COMM_TX 0x40000000
59 #define SR_COMM_RX 0x80000000
65 #define CR_RSTSTA 0x100
67 #define DEFAULT_CHIPID 0x275b0940
69 typedef struct DBGUState
{
87 static void at91_dbgu_update_irq(DBGUState
*s
)
89 qemu_set_irq(s
->irq
, !!(s
->sr
& s
->imr
));
92 static void at91_dbgu_update_parameters(DBGUState
*s
)
94 QEMUSerialSetParams ssp
;
99 ssp
.speed
= at91_master_clock_frequency
/ s
->brgr
;
101 ssp
.speed
= at91_master_clock_frequency
/ (16 * s
->brgr
);
105 qemu_chr_ioctl(s
->chr
, CHR_IOCTL_SERIAL_SET_PARAMS
, &ssp
);
108 static void at91_dbgu_receive(void *opaque
, const uint8_t *buf
, int size
)
110 DBGUState
*s
= opaque
;
112 s
->sr
|= SR_RXRDY
| SR_RXBUFF
;
113 s
->rhr
= (buf
[0] & 0xff);
114 at91_dbgu_update_irq(s
);
117 static int at91_dbgu_can_receive(void *opaque
)
119 DBGUState
*s
= opaque
;
121 if (s
->rx_enabled
&& !(s
->sr
& SR_RXRDY
))
126 static void at91_dbgu_event(void *opaque
, int event
)
130 static uint32_t at91_dbgu_mem_read(void *opaque
, target_phys_addr_t offset
)
132 DBGUState
*s
= opaque
;
135 offset
&= DBGU_SIZE
- 1;
145 s
->sr
&= ~(SR_RXRDY
| SR_RXBUFF
);
146 at91_dbgu_update_irq(s
);
153 return s
->chipid_ext
;
161 static void at91_dbgu_mem_write(void *opaque
, target_phys_addr_t offset
,
164 DBGUState
*s
= opaque
;
165 unsigned char ch
= value
;
167 offset
&= DBGU_SIZE
- 1;
170 if (value
& CR_RXDIS
) {
172 } else if (value
& CR_RXEN
) {
175 if (value
& CR_TXDIS
) {
177 } else if (value
& CR_TXEN
) {
180 if (value
& CR_RSTSTA
) {
181 s
->sr
&= ~(SR_PARE
| SR_FRAME
| SR_OVRE
);
196 /* TODO: shift register, error checking */
198 qemu_chr_write(s
->chr
, &ch
, 1);
199 s
->sr
|= SR_TXRDY
| SR_TXBUFE
| SR_TXEMPTY
;
204 at91_dbgu_update_parameters(s
);
213 at91_dbgu_update_irq(s
);
217 static uint32_t at91_dbgu_mem_read_dbg(void *opaque
, target_phys_addr_t offset
)
219 uint32_t value
= at91_dbgu_mem_read(opaque
, offset
);
220 printf("%s offset=%x val=%x\n", __func__
, offset
, value
);
224 static void at91_dbgu_mem_write_dbg(void *opaque
, target_phys_addr_t offset
,
227 printf("%s offset=%x val=%x\n", __func__
, offset
, value
);
228 at91_dbgu_mem_write(opaque
, offset
, value
);
231 #define at91_dbgu_mem_read at91_dbgu_mem_read_dbg
232 #define at91_dbgu_mem_write at91_dbgu_mem_write_dbg
235 static CPUReadMemoryFunc
*at91_dbgu_readfn
[] = {
241 static CPUWriteMemoryFunc
*at91_dbgu_writefn
[] = {
247 static void at91_dbgu_save(QEMUFile
*f
, void *opaque
)
249 DBGUState
*s
= opaque
;
251 qemu_put_byte(f
, s
->rx_enabled
);
252 qemu_put_byte(f
, s
->tx_enabled
);
253 qemu_put_be32(f
, s
->mr
);
254 qemu_put_be32(f
, s
->imr
);
255 qemu_put_be32(f
, s
->sr
);
256 qemu_put_byte(f
, s
->rhr
);
257 qemu_put_byte(f
, s
->thr
);
258 qemu_put_be16(f
, s
->brgr
);
259 qemu_put_be32(f
, s
->fnr
);
262 static int at91_dbgu_load(QEMUFile
*f
, void *opaque
, int version_id
)
264 DBGUState
*s
= opaque
;
269 s
->rx_enabled
= qemu_get_byte(f
);
270 s
->tx_enabled
= qemu_get_byte(f
);
271 s
->mr
= qemu_get_be32(f
);
272 s
->imr
= qemu_get_be32(f
);
273 s
->sr
= qemu_get_be32(f
);
274 s
->rhr
= qemu_get_byte(f
);
275 s
->thr
= qemu_get_byte(f
);
276 s
->brgr
= qemu_get_be16(f
);
277 s
->fnr
= qemu_get_be32(f
);
282 static void at91_dbgu_reset(void *opaque
)
284 DBGUState
*s
= opaque
;
290 /* Transmitter begins ready and idle */
291 s
->sr
= SR_TXRDY
| SR_TXBUFE
| SR_TXEMPTY
;
298 static void at91_dbgu_init(SysBusDevice
*dev
)
300 DBGUState
*s
= FROM_SYSBUS(typeof (*s
), dev
);
303 sysbus_init_irq(dev
, &s
->irq
);
304 ser_regs
= cpu_register_io_memory(at91_dbgu_readfn
, at91_dbgu_writefn
, s
);
305 sysbus_init_mmio(dev
, DBGU_SIZE
, ser_regs
);
306 s
->chr
= qdev_init_chardev(&dev
->qdev
);
308 qemu_chr_add_handlers(s
->chr
, at91_dbgu_can_receive
,
309 at91_dbgu_receive
, at91_dbgu_event
, s
);
313 qemu_register_reset(at91_dbgu_reset
, s
);
315 register_savevm("at91_dbgu", -1, 1, at91_dbgu_save
, at91_dbgu_load
, s
);
318 static SysBusDeviceInfo at91_dbgu_info
= {
319 .init
= at91_dbgu_init
,
320 .qdev
.name
= "at91,dbgu",
321 .qdev
.size
= sizeof(DBGUState
),
322 .qdev
.props
= (Property
[]) {
325 .info
= &qdev_prop_uint32
,
326 .offset
= offsetof(DBGUState
, chipid
),
327 .defval
= (uint32_t[]) { DEFAULT_CHIPID
},
330 .name
= "chipid-ext",
331 .info
= &qdev_prop_uint32
,
332 .offset
= offsetof(DBGUState
, chipid_ext
)
338 static void at91_dbgu_register(void)
340 sysbus_register_withprop(&at91_dbgu_info
);
343 device_init(at91_dbgu_register
)