Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
/* 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;
}
Ejemplo n.º 3
0
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;
}
/* Send enqueued characters from tx_fifo and trigger TX interrupt.
Receive characters into rx_fifo and trigger RX interrupt. */
void
tx3904sio_tickle(struct hw *me)
{
  struct tx3904sio* controller = hw_data(me);
  int c;
  char cc;
  unsigned_4 last_int, next_int;

  /* HW_TRACE ((me, "tickle backend: %02x", controller->backend)); */
  switch(controller->backend) 
    {
    case sio_tcp:

      while(tx3904sio_fifo_nonempty(me, & controller->tx_fifo))
	{
	  cc = tx3904sio_fifo_pop(me, & controller->tx_fifo);
	  dv_sockser_write(hw_system(me), cc);
	  HW_TRACE ((me, "tcp output: %02x", cc));
	}

      c = dv_sockser_read(hw_system(me));
      while(c != -1)
	{
	  cc = (char) c;
	  HW_TRACE ((me, "tcp input: %02x", cc));
	  tx3904sio_fifo_push(me, & controller->rx_fifo, cc);
	  c = dv_sockser_read(hw_system(me));
	}
      break;

    case sio_stdio:

      while(tx3904sio_fifo_nonempty(me, & controller->tx_fifo))
	{
	  cc = tx3904sio_fifo_pop(me, & controller->tx_fifo);
	  sim_io_write_stdout(hw_system(me), & cc, 1);
	  sim_io_flush_stdout(hw_system(me));
	  HW_TRACE ((me, "stdio output: %02x", cc));
	}

      c = sim_io_poll_read(hw_system(me), 0 /* stdin */, & cc, 1);
      while(c == 1)
	{
	  HW_TRACE ((me, "stdio input: %02x", cc));
	  tx3904sio_fifo_push(me, & controller->rx_fifo, cc);
	  c = sim_io_poll_read(hw_system(me), 0 /* stdin */, & cc, 1);
	}

      break;

    default:
      hw_abort(me, "Illegal backend mode: %d", controller->backend);
    }

  /* Update RDIS / TDIS flags */
  last_int = controller->sdisr & controller->sdicr;
  /* HW_TRACE ((me, "tickle - sdisr %08x sdicr %08x", controller->sdisr, controller->sdicr)); */
  if(tx3904sio_fifo_nonempty(me, & controller->rx_fifo))
    SDISR_SET_RDIS(controller);
  if(! tx3904sio_fifo_nonempty(me, & controller->tx_fifo))
    SDISR_SET_TDIS(controller);
  next_int = controller->sdisr & controller->sdicr;
  /* HW_TRACE ((me, "tickle + sdisr %08x sdicr %08x", controller->sdisr, controller->sdicr)); */

  if(~last_int & next_int) /* any bits set? */
    hw_port_event(me, INT_PORT, 1);
  if(last_int & ~next_int) /* any bits cleared? */
    hw_port_event(me, INT_PORT, 0);

  /* Add periodic polling for this port, if it's not already going. */
  if(controller->poll_event == NULL)
    {
      controller->poll_event = hw_event_queue_schedule (me, 1000,
							tx3904sio_poll, NULL);

    }
}
Ejemplo n.º 5
0
void
m68hc11sio_rx_poll (struct hw *me, void *data)
{
  SIM_DESC sd;
  struct m68hc11sio *controller;
  sim_cpu *cpu;
  char cc;
  int cnt;
  int check_interrupt = 0;
  
  controller = hw_data (me);
  sd         = hw_system (me);
  cpu        = STATE_CPU (sd, 0);
  switch (controller->backend)
    {
    case sio_tcp:
      cnt = dv_sockser_read (sd);
      if (cnt != -1)
        {
          cc = (char) cnt;
          cnt = 1;
        }
      break;

    case sio_stdio:
      cnt = sim_io_poll_read (sd, 0 /* stdin */, &cc, 1);
      break;

    default:
      cnt = 0;
      break;
    }

  if (cnt == 1)
    {
      /* Raise the overrun flag if the previous character was not read.  */
      if (cpu->ios[M6811_SCSR] & M6811_RDRF)
        cpu->ios[M6811_SCSR] |= M6811_OR;

      cpu->ios[M6811_SCSR]     |= M6811_RDRF;
      controller->rx_char       = cc;
      controller->rx_clear_scsr = 0;
      check_interrupt = 1;
    }
  else
    {
      /* handle idle line detect here.  */
      ;
    }

  if (controller->rx_poll_event)
    {
      hw_event_queue_deschedule (me, controller->rx_poll_event);
      controller->rx_poll_event = 0;
    }

  if (cpu->ios[M6811_SCCR2] & M6811_RE)
    {
      unsigned long clock_cycle;

      /* Compute CPU clock cycles to wait for the next character.  */
      clock_cycle = controller->data_length * controller->baud_cycle;

      controller->rx_poll_event = hw_event_queue_schedule (me, clock_cycle,
                                                           m68hc11sio_rx_poll,
                                                           NULL);
    }

  if (check_interrupt)
      interrupts_update_pending (&cpu->cpu_interrupts);
}