gas/
[deliverable/binutils-gdb.git] / sim / bfin / dv-bfin_uart.c
index 76aa87dcd2ee8996c87c0d6bab10bee961df24f8..859f9904260a18a2a92730e14e6a1bef7befa400 100644 (file)
@@ -1,7 +1,7 @@
 /* Blackfin Universal Asynchronous Receiver/Transmitter (UART) model.
    For "old style" UARTs on BF53x/etc... parts.
 
-   Copyright (C) 2010-2011 Free Software Foundation, Inc.
+   Copyright (C) 2010-2013 Free Software Foundation, Inc.
    Contributed by Analog Devices, Inc.
 
    This file is part of simulators.
@@ -117,10 +117,21 @@ bfin_uart_reschedule (struct hw *me)
 }
 
 bu16
-bfin_uart_write_byte (struct hw *me, bu16 thr)
+bfin_uart_write_byte (struct hw *me, bu16 thr, bu16 mcr)
 {
+  struct bfin_uart *uart = hw_data (me);
   unsigned char ch = thr;
+
+  if (mcr & LOOP_ENA)
+    {
+      /* XXX: This probably doesn't work exactly right with
+              external FIFOs ...  */
+      uart->saved_byte = thr;
+      uart->saved_count = 1;
+    }
+
   bfin_uart_write_buffer (me, &ch, 1);
+
   return thr;
 }
 
@@ -149,7 +160,7 @@ bfin_uart_io_write_buffer (struct hw *me, const void *source,
        uart->dll = value;
       else
        {
-         uart->thr = bfin_uart_write_byte (me, value);
+         uart->thr = bfin_uart_write_byte (me, value, uart->mcr);
 
          if (uart->ier & ETBEI)
            hw_port_event (me, DV_PORT_TX, 1);
@@ -184,7 +195,7 @@ bfin_uart_io_write_buffer (struct hw *me, const void *source,
 
 /* Switch between socket and stdin on the fly.  */
 bu16
-bfin_uart_get_next_byte (struct hw *me, bu16 rbr, bool *fresh)
+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);
@@ -197,23 +208,26 @@ bfin_uart_get_next_byte (struct hw *me, bu16 rbr, bool *fresh)
     fresh = &_fresh;
 
   *fresh = false;
-  if (status & DV_SOCKSER_DISCONNECTED)
+
+  if (uart->saved_count > 0)
+    {
+      *fresh = true;
+      rbr = uart->saved_byte;
+      --uart->saved_count;
+    }
+  else if (mcr & LOOP_ENA)
     {
-      if (uart->saved_count > 0)
+      /* 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 = uart->saved_byte;
-         --uart->saved_count;
-       }
-      else
-       {
-         char byte;
-         int ret = sim_io_poll_read (sd, 0/*STDIN*/, &byte, 1);
-         if (ret > 0)
-           {
-             *fresh = true;
-             rbr = byte;
-           }
+         rbr = byte;
        }
     }
   else
@@ -239,7 +253,7 @@ bfin_uart_get_status (struct hw *me)
     }
   else
     lsr |= (status & DV_SOCKSER_INPUT_EMPTY ? 0 : DR) |
-                (status & DV_SOCKSER_OUTPUT_EMPTY ? TEMT | THRE : 0);
+          (status & DV_SOCKSER_OUTPUT_EMPTY ? TEMT | THRE : 0);
 
   return lsr;
 }
@@ -266,7 +280,7 @@ bfin_uart_io_read_buffer (struct hw *me, void *dest,
        dv_store_2 (dest, uart->dll);
       else
        {
-         uart->rbr = bfin_uart_get_next_byte (me, uart->rbr, NULL);
+         uart->rbr = bfin_uart_get_next_byte (me, uart->rbr, uart->mcr, NULL);
          dv_store_2 (dest, uart->rbr);
        }
       break;
@@ -433,7 +447,8 @@ bfin_uart_finish (struct hw *me)
   uart->lsr = 0x0060;
 }
 
-const struct hw_descriptor dv_bfin_uart_descriptor[] = {
+const struct hw_descriptor dv_bfin_uart_descriptor[] =
+{
   {"bfin_uart", bfin_uart_finish,},
   {NULL, NULL},
 };
This page took 0.024741 seconds and 4 git commands to generate.