1 1.1 christos /* This file is part of the program GDB, the GNU debugger. 2 1.1 christos 3 1.11 christos Copyright (C) 1998-2024 Free Software Foundation, Inc. 4 1.1 christos Contributed by Cygnus Solutions. 5 1.1 christos 6 1.1 christos This program is free software; you can redistribute it and/or modify 7 1.1 christos it under the terms of the GNU General Public License as published by 8 1.1 christos the Free Software Foundation; either version 3 of the License, or 9 1.1 christos (at your option) any later version. 10 1.1 christos 11 1.1 christos This program is distributed in the hope that it will be useful, 12 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 1.1 christos GNU General Public License for more details. 15 1.1 christos 16 1.1 christos You should have received a copy of the GNU General Public License 17 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. 18 1.1 christos 19 1.1 christos */ 20 1.1 christos 21 1.10 christos /* This must come before any other includes. */ 22 1.10 christos #include "defs.h" 23 1.10 christos 24 1.1 christos #include "sim-main.h" 25 1.1 christos #include "hw-main.h" 26 1.1 christos #include "dv-sockser.h" 27 1.1 christos 28 1.1 christos 29 1.1 christos /* DEVICE 30 1.1 christos 31 1.1 christos 32 1.1 christos mn103ser - mn103002 serial devices 0, 1 and 2. 33 1.1 christos 34 1.1 christos 35 1.1 christos DESCRIPTION 36 1.1 christos 37 1.1 christos Implements the mn103002 serial interfaces as described in the 38 1.1 christos mn103002 user guide. 39 1.1 christos 40 1.1 christos 41 1.1 christos PROPERTIES 42 1.1 christos 43 1.1 christos reg = <serial-addr> <serial-size> 44 1.1 christos 45 1.1 christos 46 1.1 christos BUGS 47 1.1 christos 48 1.1 christos */ 49 1.1 christos 50 1.1 christos 51 1.1 christos /* The serial devices' registers' address block */ 52 1.1 christos 53 1.1 christos struct mn103ser_block { 54 1.1 christos unsigned_word base; 55 1.1 christos unsigned_word bound; 56 1.1 christos }; 57 1.1 christos 58 1.1 christos 59 1.1 christos 60 1.1 christos enum serial_register_types { 61 1.1 christos SC0CTR, 62 1.1 christos SC1CTR, 63 1.1 christos SC2CTR, 64 1.1 christos SC0ICR, 65 1.1 christos SC1ICR, 66 1.1 christos SC2ICR, 67 1.1 christos SC0TXB, 68 1.1 christos SC1TXB, 69 1.1 christos SC2TXB, 70 1.1 christos SC0RXB, 71 1.1 christos SC1RXB, 72 1.1 christos SC2RXB, 73 1.1 christos SC0STR, 74 1.1 christos SC1STR, 75 1.1 christos SC2STR, 76 1.1 christos SC2TIM, 77 1.1 christos }; 78 1.1 christos 79 1.1 christos 80 1.1 christos #define NR_SERIAL_DEVS 3 81 1.1 christos #define SIO_STAT_RRDY 0x0010 82 1.1 christos 83 1.1 christos typedef struct _mn10300_serial { 84 1.10 christos uint16_t status, control; 85 1.10 christos uint8_t txb, rxb, intmode; 86 1.1 christos struct hw_event *event; 87 1.1 christos } mn10300_serial; 88 1.1 christos 89 1.1 christos 90 1.1 christos 91 1.1 christos struct mn103ser { 92 1.1 christos struct mn103ser_block block; 93 1.1 christos mn10300_serial device[NR_SERIAL_DEVS]; 94 1.10 christos uint8_t serial2_timer_reg; 95 1.1 christos do_hw_poll_read_method *reader; 96 1.1 christos }; 97 1.1 christos 98 1.1 christos /* output port ID's */ 99 1.1 christos 100 1.1 christos /* for mn103002 */ 101 1.1 christos enum { 102 1.1 christos SERIAL0_RECEIVE, 103 1.1 christos SERIAL1_RECEIVE, 104 1.1 christos SERIAL2_RECEIVE, 105 1.1 christos SERIAL0_SEND, 106 1.1 christos SERIAL1_SEND, 107 1.1 christos SERIAL2_SEND, 108 1.1 christos }; 109 1.1 christos 110 1.1 christos 111 1.1 christos static const struct hw_port_descriptor mn103ser_ports[] = { 112 1.1 christos 113 1.1 christos { "serial-0-receive", SERIAL0_RECEIVE, 0, output_port, }, 114 1.1 christos { "serial-1-receive", SERIAL1_RECEIVE, 0, output_port, }, 115 1.1 christos { "serial-2-receive", SERIAL2_RECEIVE, 0, output_port, }, 116 1.1 christos { "serial-0-transmit", SERIAL0_SEND, 0, output_port, }, 117 1.1 christos { "serial-1-transmit", SERIAL1_SEND, 0, output_port, }, 118 1.1 christos { "serial-2-transmit", SERIAL2_SEND, 0, output_port, }, 119 1.1 christos 120 1.1 christos { NULL, }, 121 1.1 christos }; 122 1.1 christos 123 1.1 christos 124 1.1 christos 125 1.1 christos /* Finish off the partially created hw device. Attach our local 126 1.1 christos callbacks. Wire up our port names etc */ 127 1.1 christos 128 1.1 christos static hw_io_read_buffer_method mn103ser_io_read_buffer; 129 1.1 christos static hw_io_write_buffer_method mn103ser_io_write_buffer; 130 1.1 christos 131 1.1 christos static void 132 1.1 christos attach_mn103ser_regs (struct hw *me, 133 1.1 christos struct mn103ser *serial) 134 1.1 christos { 135 1.1 christos unsigned_word attach_address; 136 1.1 christos int attach_space; 137 1.1 christos unsigned attach_size; 138 1.1 christos reg_property_spec reg; 139 1.1 christos 140 1.1 christos if (hw_find_property (me, "reg") == NULL) 141 1.1 christos hw_abort (me, "Missing \"reg\" property"); 142 1.1 christos 143 1.1 christos if (!hw_find_reg_array_property (me, "reg", 0, ®)) 144 1.1 christos hw_abort (me, "\"reg\" property must contain three addr/size entries"); 145 1.1 christos hw_unit_address_to_attach_address (hw_parent (me), 146 1.1 christos ®.address, 147 1.1 christos &attach_space, 148 1.1 christos &attach_address, 149 1.1 christos me); 150 1.1 christos serial->block.base = attach_address; 151 1.1 christos hw_unit_size_to_attach_size (hw_parent (me), 152 1.1 christos ®.size, 153 1.1 christos &attach_size, me); 154 1.1 christos serial->block.bound = attach_address + (attach_size - 1); 155 1.1 christos hw_attach_address (hw_parent (me), 156 1.1 christos 0, 157 1.1 christos attach_space, attach_address, attach_size, 158 1.1 christos me); 159 1.1 christos } 160 1.1 christos 161 1.1 christos static void 162 1.1 christos mn103ser_finish (struct hw *me) 163 1.1 christos { 164 1.1 christos struct mn103ser *serial; 165 1.1 christos int i; 166 1.1 christos 167 1.1 christos serial = HW_ZALLOC (me, struct mn103ser); 168 1.1 christos set_hw_data (me, serial); 169 1.1 christos set_hw_io_read_buffer (me, mn103ser_io_read_buffer); 170 1.1 christos set_hw_io_write_buffer (me, mn103ser_io_write_buffer); 171 1.1 christos set_hw_ports (me, mn103ser_ports); 172 1.1 christos 173 1.1 christos /* Attach ourself to our parent bus */ 174 1.1 christos attach_mn103ser_regs (me, serial); 175 1.1 christos 176 1.1 christos /* If so configured, enable polled input */ 177 1.1 christos if (hw_find_property (me, "poll?") != NULL 178 1.1 christos && hw_find_boolean_property (me, "poll?")) 179 1.1 christos { 180 1.1 christos serial->reader = sim_io_poll_read; 181 1.1 christos } 182 1.1 christos else 183 1.1 christos { 184 1.1 christos serial->reader = sim_io_read; 185 1.1 christos } 186 1.1 christos 187 1.1 christos /* Initialize the serial device registers. */ 188 1.1 christos for ( i=0; i<NR_SERIAL_DEVS; ++i ) 189 1.1 christos { 190 1.1 christos serial->device[i].txb = 0; 191 1.1 christos serial->device[i].rxb = 0; 192 1.1 christos serial->device[i].status = 0; 193 1.1 christos serial->device[i].control = 0; 194 1.1 christos serial->device[i].intmode = 0; 195 1.1 christos serial->device[i].event = NULL; 196 1.1 christos } 197 1.1 christos } 198 1.1 christos 199 1.1 christos 200 1.1 christos /* read and write */ 201 1.1 christos 202 1.1 christos static int 203 1.1 christos decode_addr (struct hw *me, 204 1.1 christos struct mn103ser *serial, 205 1.1 christos unsigned_word address) 206 1.1 christos { 207 1.1 christos unsigned_word offset; 208 1.1 christos offset = address - serial->block.base; 209 1.1 christos switch (offset) 210 1.1 christos { 211 1.1 christos case 0x00: return SC0CTR; 212 1.1 christos case 0x04: return SC0ICR; 213 1.1 christos case 0x08: return SC0TXB; 214 1.1 christos case 0x09: return SC0RXB; 215 1.1 christos case 0x0C: return SC0STR; 216 1.1 christos case 0x10: return SC1CTR; 217 1.1 christos case 0x14: return SC1ICR; 218 1.1 christos case 0x18: return SC1TXB; 219 1.1 christos case 0x19: return SC1RXB; 220 1.1 christos case 0x1C: return SC1STR; 221 1.1 christos case 0x20: return SC2CTR; 222 1.1 christos case 0x24: return SC2ICR; 223 1.1 christos case 0x28: return SC2TXB; 224 1.1 christos case 0x29: return SC2RXB; 225 1.1 christos case 0x2C: return SC2STR; 226 1.1 christos case 0x2D: return SC2TIM; 227 1.1 christos default: 228 1.1 christos { 229 1.1 christos hw_abort (me, "bad address"); 230 1.1 christos return -1; 231 1.1 christos } 232 1.1 christos } 233 1.1 christos } 234 1.1 christos 235 1.1 christos static void 236 1.1 christos do_polling_event (struct hw *me, 237 1.1 christos void *data) 238 1.1 christos { 239 1.1 christos SIM_DESC sd = hw_system (me); 240 1.1 christos struct mn103ser *serial = hw_data(me); 241 1.10 christos long serial_reg = (uintptr_t) data; 242 1.1 christos char c; 243 1.1 christos int count, status; 244 1.1 christos 245 1.1 christos status = dv_sockser_status (sd); 246 1.1 christos if (!(status & DV_SOCKSER_DISCONNECTED)) 247 1.1 christos { 248 1.1 christos int rd; 249 1.1 christos rd = dv_sockser_read (sd); 250 1.1 christos if(rd != -1) 251 1.1 christos { 252 1.1 christos c = (char) rd; 253 1.1 christos count = 1; 254 1.1 christos } 255 1.1 christos else 256 1.1 christos { 257 1.1 christos count = HW_IO_NOT_READY; 258 1.1 christos } 259 1.1 christos } 260 1.1 christos else 261 1.1 christos { 262 1.1 christos count = do_hw_poll_read (me, serial->reader, 263 1.1 christos 0/*STDIN*/, &c, sizeof(c)); 264 1.1 christos } 265 1.1 christos 266 1.1 christos 267 1.1 christos switch (count) 268 1.1 christos { 269 1.1 christos case HW_IO_NOT_READY: 270 1.1 christos case HW_IO_EOF: 271 1.1 christos serial->device[serial_reg].rxb = 0; 272 1.1 christos serial->device[serial_reg].status &= ~SIO_STAT_RRDY; 273 1.1 christos break; 274 1.1 christos default: 275 1.1 christos serial->device[serial_reg].rxb = c; 276 1.1 christos serial->device[serial_reg].status |= SIO_STAT_RRDY; 277 1.1 christos hw_port_event (me, serial_reg+SERIAL0_RECEIVE, 1); 278 1.1 christos } 279 1.1 christos 280 1.1 christos /* Schedule next polling event */ 281 1.1 christos serial->device[serial_reg].event 282 1.1 christos = hw_event_queue_schedule (me, 1000, 283 1.10 christos do_polling_event, (void *)(uintptr_t)serial_reg); 284 1.1 christos 285 1.1 christos } 286 1.1 christos 287 1.1 christos static void 288 1.1 christos read_control_reg (struct hw *me, 289 1.1 christos struct mn103ser *serial, 290 1.1 christos unsigned_word serial_reg, 291 1.1 christos void *dest, 292 1.1 christos unsigned nr_bytes) 293 1.1 christos { 294 1.1 christos /* really allow 1 byte read, too */ 295 1.1 christos if ( nr_bytes == 2 ) 296 1.1 christos { 297 1.10 christos *(uint16_t *)dest = H2LE_2 (serial->device[serial_reg].control); 298 1.1 christos } 299 1.1 christos else 300 1.1 christos { 301 1.1 christos hw_abort (me, "bad read size of %d bytes from SC%dCTR.", nr_bytes, 302 1.1 christos serial_reg); 303 1.1 christos } 304 1.1 christos } 305 1.1 christos 306 1.1 christos 307 1.1 christos static void 308 1.1 christos read_intmode_reg (struct hw *me, 309 1.1 christos struct mn103ser *serial, 310 1.1 christos unsigned_word serial_reg, 311 1.1 christos void *dest, 312 1.1 christos unsigned nr_bytes) 313 1.1 christos { 314 1.1 christos if ( nr_bytes == 1 ) 315 1.1 christos { 316 1.10 christos *(uint8_t *)dest = serial->device[serial_reg].intmode; 317 1.1 christos } 318 1.1 christos else 319 1.1 christos { 320 1.1 christos hw_abort (me, "bad read size of %d bytes from SC%dICR.", nr_bytes, 321 1.1 christos serial_reg); 322 1.1 christos } 323 1.1 christos } 324 1.1 christos 325 1.1 christos 326 1.1 christos static void 327 1.1 christos read_txb (struct hw *me, 328 1.1 christos struct mn103ser *serial, 329 1.1 christos unsigned_word serial_reg, 330 1.1 christos void *dest, 331 1.1 christos unsigned nr_bytes) 332 1.1 christos { 333 1.1 christos if ( nr_bytes == 1 ) 334 1.1 christos { 335 1.10 christos *(uint8_t *)dest = serial->device[serial_reg].txb; 336 1.1 christos } 337 1.1 christos else 338 1.1 christos { 339 1.1 christos hw_abort (me, "bad read size of %d bytes from SC%dTXB.", nr_bytes, 340 1.1 christos serial_reg); 341 1.1 christos } 342 1.1 christos } 343 1.1 christos 344 1.1 christos 345 1.1 christos static void 346 1.1 christos read_rxb (struct hw *me, 347 1.1 christos struct mn103ser *serial, 348 1.1 christos unsigned_word serial_reg, 349 1.1 christos void *dest, 350 1.1 christos unsigned nr_bytes) 351 1.1 christos { 352 1.1 christos if ( nr_bytes == 1 ) 353 1.1 christos { 354 1.10 christos *(uint8_t *)dest = serial->device[serial_reg].rxb; 355 1.1 christos /* Reception buffer is now empty. */ 356 1.1 christos serial->device[serial_reg].status &= ~SIO_STAT_RRDY; 357 1.1 christos } 358 1.1 christos else 359 1.1 christos { 360 1.1 christos hw_abort (me, "bad read size of %d bytes from SC%dRXB.", nr_bytes, 361 1.1 christos serial_reg); 362 1.1 christos } 363 1.1 christos } 364 1.1 christos 365 1.1 christos 366 1.1 christos static void 367 1.1 christos read_status_reg (struct hw *me, 368 1.1 christos struct mn103ser *serial, 369 1.1 christos unsigned_word serial_reg, 370 1.1 christos void *dest, 371 1.1 christos unsigned nr_bytes) 372 1.1 christos { 373 1.1 christos char c; 374 1.1 christos int count; 375 1.1 christos 376 1.1 christos if ( (serial->device[serial_reg].status & SIO_STAT_RRDY) == 0 ) 377 1.1 christos { 378 1.1 christos SIM_DESC sd = hw_system (me); 379 1.1 christos int status; 380 1.1 christos 381 1.1 christos /* FIFO is empty */ 382 1.1 christos /* Kill current poll event */ 383 1.1 christos if ( NULL != serial->device[serial_reg].event ) 384 1.1 christos { 385 1.1 christos hw_event_queue_deschedule (me, serial->device[serial_reg].event); 386 1.1 christos serial->device[serial_reg].event = NULL; 387 1.1 christos } 388 1.1 christos 389 1.1 christos status = dv_sockser_status (sd); 390 1.1 christos if (!(status & DV_SOCKSER_DISCONNECTED)) 391 1.1 christos { 392 1.1 christos int rd; 393 1.1 christos rd = dv_sockser_read (sd); 394 1.1 christos if(rd != -1) 395 1.1 christos { 396 1.1 christos c = (char) rd; 397 1.1 christos count = 1; 398 1.1 christos } 399 1.1 christos else 400 1.1 christos { 401 1.1 christos count = HW_IO_NOT_READY; 402 1.1 christos } 403 1.1 christos } 404 1.1 christos else 405 1.1 christos { 406 1.1 christos count = do_hw_poll_read (me, serial->reader, 407 1.1 christos 0/*STDIN*/, &c, sizeof(c)); 408 1.1 christos } 409 1.1 christos 410 1.1 christos switch (count) 411 1.1 christos { 412 1.1 christos case HW_IO_NOT_READY: 413 1.1 christos case HW_IO_EOF: 414 1.1 christos serial->device[serial_reg].rxb = 0; 415 1.1 christos serial->device[serial_reg].status &= ~SIO_STAT_RRDY; 416 1.1 christos break; 417 1.1 christos default: 418 1.1 christos serial->device[serial_reg].rxb = c; 419 1.1 christos serial->device[serial_reg].status |= SIO_STAT_RRDY; 420 1.1 christos hw_port_event (me, serial_reg+SERIAL0_RECEIVE, 1); 421 1.1 christos } 422 1.1 christos 423 1.1 christos /* schedule polling event */ 424 1.1 christos serial->device[serial_reg].event 425 1.1 christos = hw_event_queue_schedule (me, 1000, 426 1.1 christos do_polling_event, 427 1.10 christos (void *)(uintptr_t)serial_reg); 428 1.1 christos } 429 1.1 christos 430 1.1 christos if ( nr_bytes == 1 ) 431 1.1 christos { 432 1.10 christos *(uint8_t *)dest = (uint8_t)serial->device[serial_reg].status; 433 1.1 christos } 434 1.1 christos else if ( nr_bytes == 2 && serial_reg != SC2STR ) 435 1.1 christos { 436 1.10 christos *(uint16_t *)dest = H2LE_2 (serial->device[serial_reg].status); 437 1.1 christos } 438 1.1 christos else 439 1.1 christos { 440 1.1 christos hw_abort (me, "bad read size of %d bytes from SC%dSTR.", nr_bytes, 441 1.1 christos serial_reg); 442 1.1 christos } 443 1.1 christos } 444 1.1 christos 445 1.1 christos 446 1.1 christos static void 447 1.1 christos read_serial2_timer_reg (struct hw *me, 448 1.1 christos struct mn103ser *serial, 449 1.1 christos void *dest, 450 1.1 christos unsigned nr_bytes) 451 1.1 christos { 452 1.1 christos if ( nr_bytes == 1 ) 453 1.1 christos { 454 1.10 christos * (uint8_t *) dest = (uint8_t) serial->serial2_timer_reg; 455 1.1 christos } 456 1.1 christos else 457 1.1 christos { 458 1.1 christos hw_abort (me, "bad read size of %d bytes to SC2TIM.", nr_bytes); 459 1.1 christos } 460 1.1 christos } 461 1.1 christos 462 1.1 christos 463 1.1 christos static unsigned 464 1.1 christos mn103ser_io_read_buffer (struct hw *me, 465 1.1 christos void *dest, 466 1.1 christos int space, 467 1.1 christos unsigned_word base, 468 1.1 christos unsigned nr_bytes) 469 1.1 christos { 470 1.1 christos struct mn103ser *serial = hw_data (me); 471 1.1 christos enum serial_register_types serial_reg; 472 1.1 christos HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes)); 473 1.1 christos 474 1.1 christos serial_reg = decode_addr (me, serial, base); 475 1.1 christos switch (serial_reg) 476 1.1 christos { 477 1.1 christos /* control registers */ 478 1.1 christos case SC0CTR: 479 1.1 christos case SC1CTR: 480 1.1 christos case SC2CTR: 481 1.1 christos read_control_reg(me, serial, serial_reg-SC0CTR, dest, nr_bytes); 482 1.1 christos HW_TRACE ((me, "read - ctrl reg%d has 0x%x\n", serial_reg-SC0CTR, 483 1.10 christos *(uint8_t *)dest)); 484 1.1 christos break; 485 1.1 christos 486 1.1 christos /* interrupt mode registers */ 487 1.1 christos case SC0ICR: 488 1.1 christos case SC1ICR: 489 1.1 christos case SC2ICR: 490 1.1 christos read_intmode_reg(me, serial, serial_reg-SC0ICR, dest, nr_bytes); 491 1.1 christos HW_TRACE ((me, "read - intmode reg%d has 0x%x\n", serial_reg-SC0ICR, 492 1.10 christos *(uint8_t *)dest)); 493 1.1 christos break; 494 1.1 christos 495 1.1 christos /* transmission buffers */ 496 1.1 christos case SC0TXB: 497 1.1 christos case SC1TXB: 498 1.1 christos case SC2TXB: 499 1.1 christos read_txb(me, serial, serial_reg-SC0TXB, dest, nr_bytes); 500 1.1 christos HW_TRACE ((me, "read - txb%d has %c\n", serial_reg-SC0TXB, 501 1.1 christos *(char *)dest)); 502 1.1 christos break; 503 1.1 christos 504 1.1 christos /* reception buffers */ 505 1.1 christos case SC0RXB: 506 1.1 christos case SC1RXB: 507 1.1 christos case SC2RXB: 508 1.1 christos read_rxb(me, serial, serial_reg-SC0RXB, dest, nr_bytes); 509 1.1 christos HW_TRACE ((me, "read - rxb%d has %c\n", serial_reg-SC0RXB, 510 1.1 christos *(char *)dest)); 511 1.1 christos break; 512 1.1 christos 513 1.1 christos /* status registers */ 514 1.1 christos case SC0STR: 515 1.1 christos case SC1STR: 516 1.1 christos case SC2STR: 517 1.1 christos read_status_reg(me, serial, serial_reg-SC0STR, dest, nr_bytes); 518 1.1 christos HW_TRACE ((me, "read - status reg%d has 0x%x\n", serial_reg-SC0STR, 519 1.10 christos *(uint8_t *)dest)); 520 1.1 christos break; 521 1.1 christos 522 1.1 christos case SC2TIM: 523 1.1 christos read_serial2_timer_reg(me, serial, dest, nr_bytes); 524 1.10 christos HW_TRACE ((me, "read - serial2 timer reg %d\n", *(uint8_t *)dest)); 525 1.1 christos break; 526 1.1 christos 527 1.1 christos default: 528 1.1 christos hw_abort(me, "invalid address"); 529 1.1 christos } 530 1.1 christos 531 1.1 christos return nr_bytes; 532 1.1 christos } 533 1.1 christos 534 1.1 christos 535 1.1 christos static void 536 1.1 christos write_control_reg (struct hw *me, 537 1.1 christos struct mn103ser *serial, 538 1.1 christos unsigned_word serial_reg, 539 1.1 christos const void *source, 540 1.1 christos unsigned nr_bytes) 541 1.1 christos { 542 1.10 christos uint16_t val = LE2H_2 (*(uint16_t *)source); 543 1.1 christos 544 1.1 christos /* really allow 1 byte write, too */ 545 1.1 christos if ( nr_bytes == 2 ) 546 1.1 christos { 547 1.1 christos if ( serial_reg == 2 && (val & 0x0C04) != 0 ) 548 1.1 christos { 549 1.1 christos hw_abort(me, "Cannot write to read-only bits of SC2CTR."); 550 1.1 christos } 551 1.1 christos else 552 1.1 christos { 553 1.1 christos serial->device[serial_reg].control = val; 554 1.1 christos } 555 1.1 christos } 556 1.1 christos else 557 1.1 christos { 558 1.1 christos hw_abort (me, "bad read size of %d bytes from SC%dSTR.", nr_bytes, 559 1.1 christos serial_reg); 560 1.1 christos } 561 1.1 christos } 562 1.1 christos 563 1.1 christos 564 1.1 christos static void 565 1.1 christos write_intmode_reg (struct hw *me, 566 1.1 christos struct mn103ser *serial, 567 1.1 christos unsigned_word serial_reg, 568 1.1 christos const void *source, 569 1.1 christos unsigned nr_bytes) 570 1.1 christos { 571 1.10 christos uint8_t val = *(uint8_t *)source; 572 1.1 christos 573 1.1 christos if ( nr_bytes == 1 ) 574 1.1 christos { 575 1.1 christos /* Check for attempt to write to read-only bits of register. */ 576 1.1 christos if ( ( serial_reg == 2 && (val & 0xCA) != 0 ) 577 1.1 christos || ( serial_reg != 2 && (val & 0x4A) != 0 ) ) 578 1.1 christos { 579 1.1 christos hw_abort(me, "Cannot write to read-only bits of SC%dICR.", 580 1.1 christos serial_reg); 581 1.1 christos } 582 1.1 christos else 583 1.1 christos { 584 1.1 christos serial->device[serial_reg].intmode = val; 585 1.1 christos } 586 1.1 christos } 587 1.1 christos else 588 1.1 christos { 589 1.1 christos hw_abort (me, "bad write size of %d bytes to SC%dICR.", nr_bytes, 590 1.1 christos serial_reg); 591 1.1 christos } 592 1.1 christos } 593 1.1 christos 594 1.1 christos 595 1.1 christos static void 596 1.1 christos write_txb (struct hw *me, 597 1.1 christos struct mn103ser *serial, 598 1.1 christos unsigned_word serial_reg, 599 1.1 christos const void *source, 600 1.1 christos unsigned nr_bytes) 601 1.1 christos { 602 1.1 christos if ( nr_bytes == 1 ) 603 1.1 christos { 604 1.1 christos SIM_DESC sd = hw_system (me); 605 1.1 christos int status; 606 1.1 christos 607 1.10 christos serial->device[serial_reg].txb = *(uint8_t *)source; 608 1.1 christos 609 1.1 christos status = dv_sockser_status (sd); 610 1.1 christos if (!(status & DV_SOCKSER_DISCONNECTED)) 611 1.1 christos { 612 1.1 christos dv_sockser_write(sd, * (char*) source); 613 1.1 christos } 614 1.1 christos else 615 1.1 christos { 616 1.1 christos sim_io_write_stdout(sd, (char *)source, 1); 617 1.1 christos sim_io_flush_stdout(sd); 618 1.1 christos } 619 1.1 christos 620 1.1 christos hw_port_event (me, serial_reg+SERIAL0_SEND, 1); 621 1.1 christos } 622 1.1 christos else 623 1.1 christos { 624 1.1 christos hw_abort (me, "bad write size of %d bytes to SC%dTXB.", nr_bytes, 625 1.1 christos serial_reg); 626 1.1 christos } 627 1.1 christos } 628 1.1 christos 629 1.1 christos 630 1.1 christos static void 631 1.1 christos write_serial2_timer_reg (struct hw *me, 632 1.1 christos struct mn103ser *serial, 633 1.1 christos const void *source, 634 1.1 christos unsigned nr_bytes) 635 1.1 christos { 636 1.1 christos if ( nr_bytes == 1 ) 637 1.1 christos { 638 1.10 christos serial->serial2_timer_reg = *(uint8_t *)source; 639 1.1 christos } 640 1.1 christos else 641 1.1 christos { 642 1.1 christos hw_abort (me, "bad write size of %d bytes to SC2TIM.", nr_bytes); 643 1.1 christos } 644 1.1 christos } 645 1.1 christos 646 1.1 christos 647 1.1 christos static unsigned 648 1.1 christos mn103ser_io_write_buffer (struct hw *me, 649 1.1 christos const void *source, 650 1.1 christos int space, 651 1.1 christos unsigned_word base, 652 1.1 christos unsigned nr_bytes) 653 1.1 christos { 654 1.1 christos struct mn103ser *serial = hw_data (me); 655 1.1 christos enum serial_register_types serial_reg; 656 1.1 christos HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes)); 657 1.1 christos 658 1.1 christos serial_reg = decode_addr (me, serial, base); 659 1.1 christos switch (serial_reg) 660 1.1 christos { 661 1.1 christos /* control registers */ 662 1.1 christos case SC0CTR: 663 1.1 christos case SC1CTR: 664 1.1 christos case SC2CTR: 665 1.1 christos HW_TRACE ((me, "write - ctrl reg%d has 0x%x, nrbytes=%d.\n", 666 1.10 christos serial_reg-SC0CTR, *(uint8_t *)source, nr_bytes)); 667 1.1 christos write_control_reg(me, serial, serial_reg-SC0CTR, source, nr_bytes); 668 1.1 christos break; 669 1.1 christos 670 1.1 christos /* interrupt mode registers */ 671 1.1 christos case SC0ICR: 672 1.1 christos case SC1ICR: 673 1.1 christos case SC2ICR: 674 1.1 christos HW_TRACE ((me, "write - intmode reg%d has 0x%x, nrbytes=%d.\n", 675 1.10 christos serial_reg-SC0ICR, *(uint8_t *)source, nr_bytes)); 676 1.1 christos write_intmode_reg(me, serial, serial_reg-SC0ICR, source, nr_bytes); 677 1.1 christos break; 678 1.1 christos 679 1.1 christos /* transmission buffers */ 680 1.1 christos case SC0TXB: 681 1.1 christos case SC1TXB: 682 1.1 christos case SC2TXB: 683 1.1 christos HW_TRACE ((me, "write - txb%d has %c, nrbytes=%d.\n", 684 1.1 christos serial_reg-SC0TXB, *(char *)source, nr_bytes)); 685 1.1 christos write_txb(me, serial, serial_reg-SC0TXB, source, nr_bytes); 686 1.1 christos break; 687 1.1 christos 688 1.1 christos /* reception buffers */ 689 1.1 christos case SC0RXB: 690 1.1 christos case SC1RXB: 691 1.1 christos case SC2RXB: 692 1.1 christos hw_abort(me, "Cannot write to reception buffer."); 693 1.1 christos break; 694 1.1 christos 695 1.1 christos /* status registers */ 696 1.1 christos case SC0STR: 697 1.1 christos case SC1STR: 698 1.1 christos case SC2STR: 699 1.1 christos hw_abort(me, "Cannot write to status register."); 700 1.1 christos break; 701 1.1 christos 702 1.1 christos case SC2TIM: 703 1.1 christos HW_TRACE ((me, "read - serial2 timer reg %d (nrbytes=%d)\n", 704 1.10 christos *(uint8_t *)source, nr_bytes)); 705 1.1 christos write_serial2_timer_reg(me, serial, source, nr_bytes); 706 1.1 christos break; 707 1.1 christos 708 1.1 christos default: 709 1.1 christos hw_abort(me, "invalid address"); 710 1.1 christos } 711 1.1 christos 712 1.1 christos return nr_bytes; 713 1.1 christos } 714 1.1 christos 715 1.1 christos 716 1.1 christos const struct hw_descriptor dv_mn103ser_descriptor[] = { 717 1.1 christos { "mn103ser", mn103ser_finish, }, 718 1.1 christos { NULL }, 719 1.1 christos }; 720