|
|
1.1 root 1: /*
2: * QEMU GRLIB APB UART Emulator
3: *
4: * Copyright (c) 2010-2011 AdaCore
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:
25: #include "sysbus.h"
26: #include "qemu-char.h"
27:
28: #include "trace.h"
29:
30: #define UART_REG_SIZE 20 /* Size of memory mapped registers */
31:
32: /* UART status register fields */
33: #define UART_DATA_READY (1 << 0)
34: #define UART_TRANSMIT_SHIFT_EMPTY (1 << 1)
35: #define UART_TRANSMIT_FIFO_EMPTY (1 << 2)
36: #define UART_BREAK_RECEIVED (1 << 3)
37: #define UART_OVERRUN (1 << 4)
38: #define UART_PARITY_ERROR (1 << 5)
39: #define UART_FRAMING_ERROR (1 << 6)
40: #define UART_TRANSMIT_FIFO_HALF (1 << 7)
41: #define UART_RECEIVE_FIFO_HALF (1 << 8)
42: #define UART_TRANSMIT_FIFO_FULL (1 << 9)
43: #define UART_RECEIVE_FIFO_FULL (1 << 10)
44:
45: /* UART control register fields */
46: #define UART_RECEIVE_ENABLE (1 << 0)
47: #define UART_TRANSMIT_ENABLE (1 << 1)
48: #define UART_RECEIVE_INTERRUPT (1 << 2)
49: #define UART_TRANSMIT_INTERRUPT (1 << 3)
50: #define UART_PARITY_SELECT (1 << 4)
51: #define UART_PARITY_ENABLE (1 << 5)
52: #define UART_FLOW_CONTROL (1 << 6)
53: #define UART_LOOPBACK (1 << 7)
54: #define UART_EXTERNAL_CLOCK (1 << 8)
55: #define UART_RECEIVE_FIFO_INTERRUPT (1 << 9)
56: #define UART_TRANSMIT_FIFO_INTERRUPT (1 << 10)
57: #define UART_FIFO_DEBUG_MODE (1 << 11)
58: #define UART_OUTPUT_ENABLE (1 << 12)
59: #define UART_FIFO_AVAILABLE (1 << 31)
60:
61: /* Memory mapped register offsets */
62: #define DATA_OFFSET 0x00
63: #define STATUS_OFFSET 0x04
64: #define CONTROL_OFFSET 0x08
65: #define SCALER_OFFSET 0x0C /* not supported */
66: #define FIFO_DEBUG_OFFSET 0x10 /* not supported */
67:
68: typedef struct UART {
69: SysBusDevice busdev;
70:
71: qemu_irq irq;
72:
73: CharDriverState *chr;
74:
75: /* registers */
76: uint32_t receive;
77: uint32_t status;
78: uint32_t control;
79: } UART;
80:
81: static int grlib_apbuart_can_receive(void *opaque)
82: {
83: UART *uart = opaque;
84:
85: return !!(uart->status & UART_DATA_READY);
86: }
87:
88: static void grlib_apbuart_receive(void *opaque, const uint8_t *buf, int size)
89: {
90: UART *uart = opaque;
91:
92: uart->receive = *buf;
93: uart->status |= UART_DATA_READY;
94:
95: if (uart->control & UART_RECEIVE_INTERRUPT) {
96: qemu_irq_pulse(uart->irq);
97: }
98: }
99:
100: static void grlib_apbuart_event(void *opaque, int event)
101: {
102: trace_grlib_apbuart_event(event);
103: }
104:
105: static void
106: grlib_apbuart_writel(void *opaque, target_phys_addr_t addr, uint32_t value)
107: {
108: UART *uart = opaque;
109: unsigned char c = 0;
110:
111: addr &= 0xff;
112:
113: /* Unit registers */
114: switch (addr) {
115: case DATA_OFFSET:
116: c = value & 0xFF;
117: qemu_chr_write(uart->chr, &c, 1);
118: return;
119:
120: case STATUS_OFFSET:
121: /* Read Only */
122: return;
123:
124: case CONTROL_OFFSET:
125: /* Not supported */
126: return;
127:
128: case SCALER_OFFSET:
129: /* Not supported */
130: return;
131:
132: default:
133: break;
134: }
135:
1.1.1.2 ! root 136: trace_grlib_apbuart_writel_unknown(addr, value);
1.1 root 137: }
138:
139: static CPUReadMemoryFunc * const grlib_apbuart_read[] = {
140: NULL, NULL, NULL,
141: };
142:
143: static CPUWriteMemoryFunc * const grlib_apbuart_write[] = {
144: NULL, NULL, grlib_apbuart_writel,
145: };
146:
147: static int grlib_apbuart_init(SysBusDevice *dev)
148: {
149: UART *uart = FROM_SYSBUS(typeof(*uart), dev);
150: int uart_regs = 0;
151:
152: qemu_chr_add_handlers(uart->chr,
153: grlib_apbuart_can_receive,
154: grlib_apbuart_receive,
155: grlib_apbuart_event,
156: uart);
157:
158: sysbus_init_irq(dev, &uart->irq);
159:
160: uart_regs = cpu_register_io_memory(grlib_apbuart_read,
161: grlib_apbuart_write,
162: uart, DEVICE_NATIVE_ENDIAN);
163: if (uart_regs < 0) {
164: return -1;
165: }
166:
167: sysbus_init_mmio(dev, UART_REG_SIZE, uart_regs);
168:
169: return 0;
170: }
171:
172: static SysBusDeviceInfo grlib_gptimer_info = {
173: .init = grlib_apbuart_init,
174: .qdev.name = "grlib,apbuart",
175: .qdev.size = sizeof(UART),
176: .qdev.props = (Property[]) {
177: DEFINE_PROP_CHR("chrdev", UART, chr),
178: DEFINE_PROP_END_OF_LIST()
179: }
180: };
181:
182: static void grlib_gptimer_register(void)
183: {
184: sysbus_register_withprop(&grlib_gptimer_info);
185: }
186:
187: device_init(grlib_gptimer_register)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.