1 /* 2 * QEMU GRLIB APB UART Emulator 3 * 4 * Copyright (c) 2010-2019 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 "qemu/osdep.h" 26 #include "hw/irq.h" 27 #include "hw/qdev-properties.h" 28 #include "hw/sparc/grlib.h" 29 #include "hw/sysbus.h" 30 #include "qemu/module.h" 31 #include "chardev/char-fe.h" 32 33 #include "trace.h" 34 #include "qom/object.h" 35 36 #define UART_REG_SIZE 20 /* Size of memory mapped registers */ 37 38 /* UART status register fields */ 39 #define UART_DATA_READY (1 << 0) 40 #define UART_TRANSMIT_SHIFT_EMPTY (1 << 1) 41 #define UART_TRANSMIT_FIFO_EMPTY (1 << 2) 42 #define UART_BREAK_RECEIVED (1 << 3) 43 #define UART_OVERRUN (1 << 4) 44 #define UART_PARITY_ERROR (1 << 5) 45 #define UART_FRAMING_ERROR (1 << 6) 46 #define UART_TRANSMIT_FIFO_HALF (1 << 7) 47 #define UART_RECEIVE_FIFO_HALF (1 << 8) 48 #define UART_TRANSMIT_FIFO_FULL (1 << 9) 49 #define UART_RECEIVE_FIFO_FULL (1 << 10) 50 51 /* UART control register fields */ 52 #define UART_RECEIVE_ENABLE (1 << 0) 53 #define UART_TRANSMIT_ENABLE (1 << 1) 54 #define UART_RECEIVE_INTERRUPT (1 << 2) 55 #define UART_TRANSMIT_INTERRUPT (1 << 3) 56 #define UART_PARITY_SELECT (1 << 4) 57 #define UART_PARITY_ENABLE (1 << 5) 58 #define UART_FLOW_CONTROL (1 << 6) 59 #define UART_LOOPBACK (1 << 7) 60 #define UART_EXTERNAL_CLOCK (1 << 8) 61 #define UART_RECEIVE_FIFO_INTERRUPT (1 << 9) 62 #define UART_TRANSMIT_FIFO_INTERRUPT (1 << 10) 63 #define UART_FIFO_DEBUG_MODE (1 << 11) 64 #define UART_OUTPUT_ENABLE (1 << 12) 65 #define UART_FIFO_AVAILABLE (1 << 31) 66 67 /* Memory mapped register offsets */ 68 #define DATA_OFFSET 0x00 69 #define STATUS_OFFSET 0x04 70 #define CONTROL_OFFSET 0x08 71 #define SCALER_OFFSET 0x0C /* not supported */ 72 #define FIFO_DEBUG_OFFSET 0x10 /* not supported */ 73 74 #define FIFO_LENGTH 1024 75 76 typedef struct UART UART; 77 DECLARE_INSTANCE_CHECKER(UART, GRLIB_APB_UART, 78 TYPE_GRLIB_APB_UART) 79 80 struct UART { 81 SysBusDevice parent_obj; 82 83 MemoryRegion iomem; 84 qemu_irq irq; 85 86 CharBackend chr; 87 88 /* registers */ 89 uint32_t status; 90 uint32_t control; 91 92 /* FIFO */ 93 char buffer[FIFO_LENGTH]; 94 int len; 95 int current; 96 }; 97 98 static int uart_data_to_read(UART *uart) 99 { 100 return uart->current < uart->len; 101 } 102 103 static char uart_pop(UART *uart) 104 { 105 char ret; 106 107 if (uart->len == 0) { 108 uart->status &= ~UART_DATA_READY; 109 return 0; 110 } 111 112 ret = uart->buffer[uart->current++]; 113 114 if (uart->current >= uart->len) { 115 /* Flush */ 116 uart->len = 0; 117 uart->current = 0; 118 } 119 120 if (!uart_data_to_read(uart)) { 121 uart->status &= ~UART_DATA_READY; 122 } 123 124 return ret; 125 } 126 127 static void uart_add_to_fifo(UART *uart, 128 const uint8_t *buffer, 129 int length) 130 { 131 if (uart->len + length > FIFO_LENGTH) { 132 abort(); 133 } 134 memcpy(uart->buffer + uart->len, buffer, length); 135 uart->len += length; 136 } 137 138 static int grlib_apbuart_can_receive(void *opaque) 139 { 140 UART *uart = opaque; 141 142 return FIFO_LENGTH - uart->len; 143 } 144 145 static void grlib_apbuart_receive(void *opaque, const uint8_t *buf, int size) 146 { 147 UART *uart = opaque; 148 149 if (uart->control & UART_RECEIVE_ENABLE) { 150 uart_add_to_fifo(uart, buf, size); 151 152 uart->status |= UART_DATA_READY; 153 154 if (uart->control & UART_RECEIVE_INTERRUPT) { 155 qemu_irq_pulse(uart->irq); 156 } 157 } 158 } 159 160 static void grlib_apbuart_event(void *opaque, QEMUChrEvent event) 161 { 162 trace_grlib_apbuart_event(event); 163 } 164 165 166 static uint64_t grlib_apbuart_read(void *opaque, hwaddr addr, 167 unsigned size) 168 { 169 UART *uart = opaque; 170 171 addr &= 0xff; 172 173 /* Unit registers */ 174 switch (addr) { 175 case DATA_OFFSET: 176 case DATA_OFFSET + 3: /* when only one byte read */ 177 return uart_pop(uart); 178 179 case STATUS_OFFSET: 180 /* Read Only */ 181 return uart->status; 182 183 case CONTROL_OFFSET: 184 return uart->control; 185 186 case SCALER_OFFSET: 187 /* Not supported */ 188 return 0; 189 190 default: 191 trace_grlib_apbuart_readl_unknown(addr); 192 return 0; 193 } 194 } 195 196 static void grlib_apbuart_write(void *opaque, hwaddr addr, 197 uint64_t value, unsigned size) 198 { 199 UART *uart = opaque; 200 unsigned char c = 0; 201 202 addr &= 0xff; 203 204 /* Unit registers */ 205 switch (addr) { 206 case DATA_OFFSET: 207 case DATA_OFFSET + 3: /* When only one byte write */ 208 /* Transmit when character device available and transmitter enabled */ 209 if (qemu_chr_fe_backend_connected(&uart->chr) && 210 (uart->control & UART_TRANSMIT_ENABLE)) { 211 c = value & 0xFF; 212 /* XXX this blocks entire thread. Rewrite to use 213 * qemu_chr_fe_write and background I/O callbacks */ 214 qemu_chr_fe_write_all(&uart->chr, &c, 1); 215 /* Generate interrupt */ 216 if (uart->control & UART_TRANSMIT_INTERRUPT) { 217 qemu_irq_pulse(uart->irq); 218 } 219 } 220 return; 221 222 case STATUS_OFFSET: 223 /* Read Only */ 224 return; 225 226 case CONTROL_OFFSET: 227 uart->control = value; 228 return; 229 230 case SCALER_OFFSET: 231 /* Not supported */ 232 return; 233 234 default: 235 break; 236 } 237 238 trace_grlib_apbuart_writel_unknown(addr, value); 239 } 240 241 static const MemoryRegionOps grlib_apbuart_ops = { 242 .write = grlib_apbuart_write, 243 .read = grlib_apbuart_read, 244 .endianness = DEVICE_NATIVE_ENDIAN, 245 }; 246 247 static void grlib_apbuart_realize(DeviceState *dev, Error **errp) 248 { 249 UART *uart = GRLIB_APB_UART(dev); 250 SysBusDevice *sbd = SYS_BUS_DEVICE(dev); 251 252 qemu_chr_fe_set_handlers(&uart->chr, 253 grlib_apbuart_can_receive, 254 grlib_apbuart_receive, 255 grlib_apbuart_event, 256 NULL, uart, NULL, true); 257 258 sysbus_init_irq(sbd, &uart->irq); 259 260 memory_region_init_io(&uart->iomem, OBJECT(uart), &grlib_apbuart_ops, uart, 261 "uart", UART_REG_SIZE); 262 263 sysbus_init_mmio(sbd, &uart->iomem); 264 } 265 266 static void grlib_apbuart_reset(DeviceState *d) 267 { 268 UART *uart = GRLIB_APB_UART(d); 269 270 /* Transmitter FIFO and shift registers are always empty in QEMU */ 271 uart->status = UART_TRANSMIT_FIFO_EMPTY | UART_TRANSMIT_SHIFT_EMPTY; 272 /* Everything is off */ 273 uart->control = 0; 274 /* Flush receive FIFO */ 275 uart->len = 0; 276 uart->current = 0; 277 } 278 279 static Property grlib_apbuart_properties[] = { 280 DEFINE_PROP_CHR("chrdev", UART, chr), 281 DEFINE_PROP_END_OF_LIST(), 282 }; 283 284 static void grlib_apbuart_class_init(ObjectClass *klass, void *data) 285 { 286 DeviceClass *dc = DEVICE_CLASS(klass); 287 288 dc->realize = grlib_apbuart_realize; 289 dc->reset = grlib_apbuart_reset; 290 device_class_set_props(dc, grlib_apbuart_properties); 291 } 292 293 static const TypeInfo grlib_apbuart_info = { 294 .name = TYPE_GRLIB_APB_UART, 295 .parent = TYPE_SYS_BUS_DEVICE, 296 .instance_size = sizeof(UART), 297 .class_init = grlib_apbuart_class_init, 298 }; 299 300 static void grlib_apbuart_register_types(void) 301 { 302 type_register_static(&grlib_apbuart_info); 303 } 304 305 type_init(grlib_apbuart_register_types) 306