unsigned bfin_uart_read_buffer (struct hw *me, unsigned char *buffer, unsigned nr_bytes) { SIM_DESC sd = hw_system (me); struct bfin_uart *uart = hw_data (me); int status = dv_sockser_status (sd); unsigned i = 0; if (status & DV_SOCKSER_DISCONNECTED) { int ret; while (uart->saved_count > 0 && i < nr_bytes) { buffer[i++] = uart->saved_byte; --uart->saved_count; } ret = sim_io_poll_read (sd, 0/*STDIN*/, (char *) buffer, nr_bytes - i); if (ret > 0) i += ret; } else buffer[i++] = dv_sockser_read (sd); return i; }
static void write_txb (struct hw *me, struct mn103ser *serial, unsigned_word serial_reg, const void *source, unsigned nr_bytes) { if ( nr_bytes == 1 ) { SIM_DESC sd = hw_system (me); int status; serial->device[serial_reg].txb = *(unsigned8 *)source; status = dv_sockser_status (sd); if (!(status & DV_SOCKSER_DISCONNECTED)) { dv_sockser_write(sd, * (char*) source); } else { sim_io_write_stdout(sd, (char *)source, 1); sim_io_flush_stdout(sd); } hw_port_event (me, serial_reg+SERIAL0_SEND, 1); } else { hw_abort (me, "bad write size of %d bytes to SC%dTXB.", nr_bytes, serial_reg); } }
static void do_polling_event (struct hw *me, void *data) { SIM_DESC sd = hw_system (me); struct mn103ser *serial = hw_data(me); long serial_reg = (long) data; char c; int count, status; status = dv_sockser_status (sd); if (!(status & DV_SOCKSER_DISCONNECTED)) { int rd; rd = dv_sockser_read (sd); if(rd != -1) { c = (char) rd; count = 1; } else { count = HW_IO_NOT_READY; } } else { count = do_hw_poll_read (me, serial->reader, 0/*STDIN*/, &c, sizeof(c)); } switch (count) { case HW_IO_NOT_READY: case HW_IO_EOF: serial->device[serial_reg].rxb = 0; serial->device[serial_reg].status &= ~SIO_STAT_RRDY; break; default: serial->device[serial_reg].rxb = c; serial->device[serial_reg].status |= SIO_STAT_RRDY; hw_port_event (me, serial_reg+SERIAL0_RECEIVE, 1); } /* Schedule next polling event */ serial->device[serial_reg].event = hw_event_queue_schedule (me, 1000, do_polling_event, (void *)serial_reg); }
/* Switch between socket and stdin on the fly. */ bu16 bfin_uart_get_next_byte (struct hw *me, bu16 rbr, bu16 mcr, bool *fresh) { SIM_DESC sd = hw_system (me); struct bfin_uart *uart = hw_data (me); int status = dv_sockser_status (sd); bool _fresh; /* NB: The "uart" here may only use interal state. */ if (!fresh) fresh = &_fresh; *fresh = false; if (uart->saved_count > 0) { *fresh = true; rbr = uart->saved_byte; --uart->saved_count; } else if (mcr & LOOP_ENA) { /* RX is disconnected, so only return local data. */ } else if (status & DV_SOCKSER_DISCONNECTED) { char byte; int ret = sim_io_poll_read (sd, 0/*STDIN*/, &byte, 1); if (ret > 0) { *fresh = true; rbr = byte; } } else rbr = dv_sockser_read (sd); return rbr; }
unsigned bfin_uart_write_buffer (struct hw *me, const unsigned char *buffer, unsigned nr_bytes) { SIM_DESC sd = hw_system (me); int status = dv_sockser_status (sd); if (status & DV_SOCKSER_DISCONNECTED) { sim_io_write_stdout (sd, (const char *) buffer, nr_bytes); sim_io_flush_stdout (sd); } else { /* Normalize errors to a value of 0. */ int ret = dv_sockser_write_buffer (sd, buffer, nr_bytes); nr_bytes = CLAMP (ret, 0, nr_bytes); } return nr_bytes; }
bu16 bfin_uart_get_status (struct hw *me) { SIM_DESC sd = hw_system (me); struct bfin_uart *uart = hw_data (me); int status = dv_sockser_status (sd); bu16 lsr = 0; if (status & DV_SOCKSER_DISCONNECTED) { if (uart->saved_count <= 0) uart->saved_count = sim_io_poll_read (sd, 0/*STDIN*/, &uart->saved_byte, 1); lsr |= TEMT | THRE | (uart->saved_count > 0 ? DR : 0); } else lsr |= (status & DV_SOCKSER_INPUT_EMPTY ? 0 : DR) | (status & DV_SOCKSER_OUTPUT_EMPTY ? TEMT | THRE : 0); return lsr; }
static void read_status_reg (struct hw *me, struct mn103ser *serial, unsigned_word serial_reg, void *dest, unsigned nr_bytes) { char c; int count; if ( (serial->device[serial_reg].status & SIO_STAT_RRDY) == 0 ) { SIM_DESC sd = hw_system (me); int status; /* FIFO is empty */ /* Kill current poll event */ if ( NULL != serial->device[serial_reg].event ) { hw_event_queue_deschedule (me, serial->device[serial_reg].event); serial->device[serial_reg].event = NULL; } status = dv_sockser_status (sd); if (!(status & DV_SOCKSER_DISCONNECTED)) { int rd; rd = dv_sockser_read (sd); if(rd != -1) { c = (char) rd; count = 1; } else { count = HW_IO_NOT_READY; } } else { count = do_hw_poll_read (me, serial->reader, 0/*STDIN*/, &c, sizeof(c)); } switch (count) { case HW_IO_NOT_READY: case HW_IO_EOF: serial->device[serial_reg].rxb = 0; serial->device[serial_reg].status &= ~SIO_STAT_RRDY; break; default: serial->device[serial_reg].rxb = c; serial->device[serial_reg].status |= SIO_STAT_RRDY; hw_port_event (me, serial_reg+SERIAL0_RECEIVE, 1); } /* schedule polling event */ serial->device[serial_reg].event = hw_event_queue_schedule (me, 1000, do_polling_event, (void *) (long) serial_reg); } if ( nr_bytes == 1 ) { *(unsigned8 *)dest = (unsigned8)serial->device[serial_reg].status; } else if ( nr_bytes == 2 && serial_reg != SC2STR ) { *(unsigned16 *)dest = H2LE_2 (serial->device[serial_reg].status); } else { hw_abort (me, "bad read size of %d bytes from SC%dSTR.", nr_bytes, serial_reg); } }