1 /* Blackfin Universal Asynchronous Receiver/Transmitter (UART) model. 2 For "old style" UARTs on BF53x/etc... parts. 3 4 Copyright (C) 2010-2014 Free Software Foundation, Inc. 5 Contributed by Analog Devices, Inc. 6 7 This file is part of simulators. 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 3 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 21 22 #include "config.h" 23 24 #include "sim-main.h" 25 #include "dv-sockser.h" 26 #include "devices.h" 27 #include "dv-bfin_uart.h" 28 29 /* XXX: Should we bother emulating the TX/RX FIFOs ? */ 30 31 /* Internal state needs to be the same as bfin_uart2. */ 32 struct bfin_uart 33 { 34 /* This top portion matches common dv_bfin struct. */ 35 bu32 base; 36 struct hw *dma_master; 37 bool acked; 38 39 struct hw_event *handler; 40 char saved_byte; 41 int saved_count; 42 43 /* This is aliased to DLH. */ 44 bu16 ier; 45 /* These are aliased to DLL. */ 46 bu16 thr, rbr; 47 48 /* Order after here is important -- matches hardware MMR layout. */ 49 bu16 BFIN_MMR_16(dll); 50 bu16 BFIN_MMR_16(dlh); 51 bu16 BFIN_MMR_16(iir); 52 bu16 BFIN_MMR_16(lcr); 53 bu16 BFIN_MMR_16(mcr); 54 bu16 BFIN_MMR_16(lsr); 55 bu16 BFIN_MMR_16(msr); 56 bu16 BFIN_MMR_16(scr); 57 bu16 _pad0[2]; 58 bu16 BFIN_MMR_16(gctl); 59 }; 60 #define mmr_base() offsetof(struct bfin_uart, dll) 61 #define mmr_offset(mmr) (offsetof(struct bfin_uart, mmr) - mmr_base()) 62 63 static const char * const mmr_names[] = 64 { 65 "UART_RBR/UART_THR", "UART_IER", "UART_IIR", "UART_LCR", "UART_MCR", 66 "UART_LSR", "UART_MSR", "UART_SCR", "<INV>", "UART_GCTL", 67 }; 68 static const char *mmr_name (struct bfin_uart *uart, bu32 idx) 69 { 70 if (uart->lcr & DLAB) 71 if (idx < 2) 72 return idx == 0 ? "UART_DLL" : "UART_DLH"; 73 return mmr_names[idx]; 74 } 75 #define mmr_name(off) mmr_name (uart, (off) / 4) 76 77 #ifndef HAVE_DV_SOCKSER 78 # define dv_sockser_status(sd) -1 79 # define dv_sockser_write(sd, byte) do { ; } while (0) 80 # define dv_sockser_read(sd) 0xff 81 #endif 82 83 static void 84 bfin_uart_poll (struct hw *me, void *data) 85 { 86 struct bfin_uart *uart = data; 87 bu16 lsr; 88 89 uart->handler = NULL; 90 91 lsr = bfin_uart_get_status (me); 92 if (lsr & DR) 93 hw_port_event (me, DV_PORT_RX, 1); 94 95 bfin_uart_reschedule (me); 96 } 97 98 void 99 bfin_uart_reschedule (struct hw *me) 100 { 101 struct bfin_uart *uart = hw_data (me); 102 103 if (uart->ier & ERBFI) 104 { 105 if (!uart->handler) 106 uart->handler = hw_event_queue_schedule (me, 10000, 107 bfin_uart_poll, uart); 108 } 109 else 110 { 111 if (uart->handler) 112 { 113 hw_event_queue_deschedule (me, uart->handler); 114 uart->handler = NULL; 115 } 116 } 117 } 118 119 bu16 120 bfin_uart_write_byte (struct hw *me, bu16 thr, bu16 mcr) 121 { 122 struct bfin_uart *uart = hw_data (me); 123 unsigned char ch = thr; 124 125 if (mcr & LOOP_ENA) 126 { 127 /* XXX: This probably doesn't work exactly right with 128 external FIFOs ... */ 129 uart->saved_byte = thr; 130 uart->saved_count = 1; 131 } 132 133 bfin_uart_write_buffer (me, &ch, 1); 134 135 return thr; 136 } 137 138 static unsigned 139 bfin_uart_io_write_buffer (struct hw *me, const void *source, 140 int space, address_word addr, unsigned nr_bytes) 141 { 142 struct bfin_uart *uart = hw_data (me); 143 bu32 mmr_off; 144 bu32 value; 145 bu16 *valuep; 146 147 value = dv_load_2 (source); 148 mmr_off = addr - uart->base; 149 valuep = (void *)((unsigned long)uart + mmr_base() + mmr_off); 150 151 HW_TRACE_WRITE (); 152 153 dv_bfin_mmr_require_16 (me, addr, nr_bytes, true); 154 155 /* XXX: All MMRs are "8bit" ... what happens to high 8bits ? */ 156 switch (mmr_off) 157 { 158 case mmr_offset(dll): 159 if (uart->lcr & DLAB) 160 uart->dll = value; 161 else 162 { 163 uart->thr = bfin_uart_write_byte (me, value, uart->mcr); 164 165 if (uart->ier & ETBEI) 166 hw_port_event (me, DV_PORT_TX, 1); 167 } 168 break; 169 case mmr_offset(dlh): 170 if (uart->lcr & DLAB) 171 uart->dlh = value; 172 else 173 { 174 uart->ier = value; 175 bfin_uart_reschedule (me); 176 } 177 break; 178 case mmr_offset(iir): 179 case mmr_offset(lsr): 180 /* XXX: Writes are ignored ? */ 181 break; 182 case mmr_offset(lcr): 183 case mmr_offset(mcr): 184 case mmr_offset(scr): 185 case mmr_offset(gctl): 186 *valuep = value; 187 break; 188 default: 189 dv_bfin_mmr_invalid (me, addr, nr_bytes, true); 190 break; 191 } 192 193 return nr_bytes; 194 } 195 196 /* Switch between socket and stdin on the fly. */ 197 bu16 198 bfin_uart_get_next_byte (struct hw *me, bu16 rbr, bu16 mcr, bool *fresh) 199 { 200 SIM_DESC sd = hw_system (me); 201 struct bfin_uart *uart = hw_data (me); 202 int status = dv_sockser_status (sd); 203 bool _fresh; 204 205 /* NB: The "uart" here may only use interal state. */ 206 207 if (!fresh) 208 fresh = &_fresh; 209 210 *fresh = false; 211 212 if (uart->saved_count > 0) 213 { 214 *fresh = true; 215 rbr = uart->saved_byte; 216 --uart->saved_count; 217 } 218 else if (mcr & LOOP_ENA) 219 { 220 /* RX is disconnected, so only return local data. */ 221 } 222 else if (status & DV_SOCKSER_DISCONNECTED) 223 { 224 char byte; 225 int ret = sim_io_poll_read (sd, 0/*STDIN*/, &byte, 1); 226 227 if (ret > 0) 228 { 229 *fresh = true; 230 rbr = byte; 231 } 232 } 233 else 234 rbr = dv_sockser_read (sd); 235 236 return rbr; 237 } 238 239 bu16 240 bfin_uart_get_status (struct hw *me) 241 { 242 SIM_DESC sd = hw_system (me); 243 struct bfin_uart *uart = hw_data (me); 244 int status = dv_sockser_status (sd); 245 bu16 lsr = 0; 246 247 if (status & DV_SOCKSER_DISCONNECTED) 248 { 249 if (uart->saved_count <= 0) 250 uart->saved_count = sim_io_poll_read (sd, 0/*STDIN*/, 251 &uart->saved_byte, 1); 252 lsr |= TEMT | THRE | (uart->saved_count > 0 ? DR : 0); 253 } 254 else 255 lsr |= (status & DV_SOCKSER_INPUT_EMPTY ? 0 : DR) | 256 (status & DV_SOCKSER_OUTPUT_EMPTY ? TEMT | THRE : 0); 257 258 return lsr; 259 } 260 261 static unsigned 262 bfin_uart_io_read_buffer (struct hw *me, void *dest, 263 int space, address_word addr, unsigned nr_bytes) 264 { 265 struct bfin_uart *uart = hw_data (me); 266 bu32 mmr_off; 267 bu16 *valuep; 268 269 mmr_off = addr - uart->base; 270 valuep = (void *)((unsigned long)uart + mmr_base() + mmr_off); 271 272 HW_TRACE_READ (); 273 274 dv_bfin_mmr_require_16 (me, addr, nr_bytes, false); 275 276 switch (mmr_off) 277 { 278 case mmr_offset(dll): 279 if (uart->lcr & DLAB) 280 dv_store_2 (dest, uart->dll); 281 else 282 { 283 uart->rbr = bfin_uart_get_next_byte (me, uart->rbr, uart->mcr, NULL); 284 dv_store_2 (dest, uart->rbr); 285 } 286 break; 287 case mmr_offset(dlh): 288 if (uart->lcr & DLAB) 289 dv_store_2 (dest, uart->dlh); 290 else 291 dv_store_2 (dest, uart->ier); 292 break; 293 case mmr_offset(lsr): 294 /* XXX: Reads are destructive on most parts, but not all ... */ 295 uart->lsr |= bfin_uart_get_status (me); 296 dv_store_2 (dest, *valuep); 297 uart->lsr = 0; 298 break; 299 case mmr_offset(iir): 300 /* XXX: Reads are destructive ... */ 301 case mmr_offset(lcr): 302 case mmr_offset(mcr): 303 case mmr_offset(scr): 304 case mmr_offset(gctl): 305 dv_store_2 (dest, *valuep); 306 break; 307 default: 308 dv_bfin_mmr_invalid (me, addr, nr_bytes, false); 309 break; 310 } 311 312 return nr_bytes; 313 } 314 315 unsigned 316 bfin_uart_read_buffer (struct hw *me, unsigned char *buffer, unsigned nr_bytes) 317 { 318 SIM_DESC sd = hw_system (me); 319 struct bfin_uart *uart = hw_data (me); 320 int status = dv_sockser_status (sd); 321 unsigned i = 0; 322 323 if (status & DV_SOCKSER_DISCONNECTED) 324 { 325 int ret; 326 327 while (uart->saved_count > 0 && i < nr_bytes) 328 { 329 buffer[i++] = uart->saved_byte; 330 --uart->saved_count; 331 } 332 333 ret = sim_io_poll_read (sd, 0/*STDIN*/, (char *) buffer, nr_bytes - i); 334 if (ret > 0) 335 i += ret; 336 } 337 else 338 buffer[i++] = dv_sockser_read (sd); 339 340 return i; 341 } 342 343 static unsigned 344 bfin_uart_dma_read_buffer (struct hw *me, void *dest, int space, 345 unsigned_word addr, unsigned nr_bytes) 346 { 347 HW_TRACE_DMA_READ (); 348 return bfin_uart_read_buffer (me, dest, nr_bytes); 349 } 350 351 unsigned 352 bfin_uart_write_buffer (struct hw *me, const unsigned char *buffer, 353 unsigned nr_bytes) 354 { 355 SIM_DESC sd = hw_system (me); 356 int status = dv_sockser_status (sd); 357 358 if (status & DV_SOCKSER_DISCONNECTED) 359 { 360 sim_io_write_stdout (sd, (const char *) buffer, nr_bytes); 361 sim_io_flush_stdout (sd); 362 } 363 else 364 { 365 /* Normalize errors to a value of 0. */ 366 int ret = dv_sockser_write_buffer (sd, buffer, nr_bytes); 367 nr_bytes = CLAMP (ret, 0, nr_bytes); 368 } 369 370 return nr_bytes; 371 } 372 373 static unsigned 374 bfin_uart_dma_write_buffer (struct hw *me, const void *source, 375 int space, unsigned_word addr, 376 unsigned nr_bytes, 377 int violate_read_only_section) 378 { 379 struct bfin_uart *uart = hw_data (me); 380 unsigned ret; 381 382 HW_TRACE_DMA_WRITE (); 383 384 ret = bfin_uart_write_buffer (me, source, nr_bytes); 385 386 if (ret == nr_bytes && (uart->ier & ETBEI)) 387 hw_port_event (me, DV_PORT_TX, 1); 388 389 return ret; 390 } 391 392 static const struct hw_port_descriptor bfin_uart_ports[] = 393 { 394 { "tx", DV_PORT_TX, 0, output_port, }, 395 { "rx", DV_PORT_RX, 0, output_port, }, 396 { "stat", DV_PORT_STAT, 0, output_port, }, 397 { NULL, 0, 0, 0, }, 398 }; 399 400 static void 401 attach_bfin_uart_regs (struct hw *me, struct bfin_uart *uart) 402 { 403 address_word attach_address; 404 int attach_space; 405 unsigned attach_size; 406 reg_property_spec reg; 407 408 if (hw_find_property (me, "reg") == NULL) 409 hw_abort (me, "Missing \"reg\" property"); 410 411 if (!hw_find_reg_array_property (me, "reg", 0, ®)) 412 hw_abort (me, "\"reg\" property must contain three addr/size entries"); 413 414 hw_unit_address_to_attach_address (hw_parent (me), 415 ®.address, 416 &attach_space, &attach_address, me); 417 hw_unit_size_to_attach_size (hw_parent (me), ®.size, &attach_size, me); 418 419 if (attach_size != BFIN_MMR_UART_SIZE) 420 hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_UART_SIZE); 421 422 hw_attach_address (hw_parent (me), 423 0, attach_space, attach_address, attach_size, me); 424 425 uart->base = attach_address; 426 } 427 428 static void 429 bfin_uart_finish (struct hw *me) 430 { 431 struct bfin_uart *uart; 432 433 uart = HW_ZALLOC (me, struct bfin_uart); 434 435 set_hw_data (me, uart); 436 set_hw_io_read_buffer (me, bfin_uart_io_read_buffer); 437 set_hw_io_write_buffer (me, bfin_uart_io_write_buffer); 438 set_hw_dma_read_buffer (me, bfin_uart_dma_read_buffer); 439 set_hw_dma_write_buffer (me, bfin_uart_dma_write_buffer); 440 set_hw_ports (me, bfin_uart_ports); 441 442 attach_bfin_uart_regs (me, uart); 443 444 /* Initialize the UART. */ 445 uart->dll = 0x0001; 446 uart->iir = 0x0001; 447 uart->lsr = 0x0060; 448 } 449 450 const struct hw_descriptor dv_bfin_uart_descriptor[] = 451 { 452 {"bfin_uart", bfin_uart_finish,}, 453 {NULL, NULL}, 454 }; 455