/* Blackfin Universal Asynchronous Receiver/Transmitter (UART) model.
   For "old style" UARTs on BF53x/etc... parts.

   Copyright (C) 2010-2021 Free Software Foundation, Inc.
   Contributed by Analog Devices, Inc.

   This file is part of simulators.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

/* This must come before any other includes.  */
#include "defs.h"

#include "sim-main.h"
#include "dv-sockser.h"
#include "devices.h"
#include "dv-bfin_uart.h"

/* XXX: Should we bother emulating the TX/RX FIFOs ?  */

/* Internal state needs to be the same as bfin_uart2.  */
struct bfin_uart
{
  /* This top portion matches common dv_bfin struct.  */
  bu32 base;
  struct hw *dma_master;
  bool acked;

  struct hw_event *handler;
  char saved_byte;
  int saved_count;

  /* This is aliased to DLH.  */
  bu16 ier;
  /* These are aliased to DLL.  */
  bu16 thr, rbr;

  /* Order after here is important -- matches hardware MMR layout.  */
  bu16 BFIN_MMR_16(dll);
  bu16 BFIN_MMR_16(dlh);
  bu16 BFIN_MMR_16(iir);
  bu16 BFIN_MMR_16(lcr);
  bu16 BFIN_MMR_16(mcr);
  bu16 BFIN_MMR_16(lsr);
  bu16 BFIN_MMR_16(msr);
  bu16 BFIN_MMR_16(scr);
  bu16 _pad0[2];
  bu16 BFIN_MMR_16(gctl);
};
#define mmr_base()      offsetof(struct bfin_uart, dll)
#define mmr_offset(mmr) (offsetof(struct bfin_uart, mmr) - mmr_base())

static const char * const mmr_names[] =
{
  "UART_RBR/UART_THR", "UART_IER", "UART_IIR", "UART_LCR", "UART_MCR",
  "UART_LSR", "UART_MSR", "UART_SCR", "<INV>", "UART_GCTL",
};
static const char *mmr_name (struct bfin_uart *uart, bu32 idx)
{
  if (uart->lcr & DLAB)
    if (idx < 2)
      return idx == 0 ? "UART_DLL" : "UART_DLH";
  return mmr_names[idx];
}
#define mmr_name(off) mmr_name (uart, (off) / 4)

static void
bfin_uart_poll (struct hw *me, void *data)
{
  struct bfin_uart *uart = data;
  bu16 lsr;

  uart->handler = NULL;

  lsr = bfin_uart_get_status (me);
  if (lsr & DR)
    hw_port_event (me, DV_PORT_RX, 1);

  bfin_uart_reschedule (me);
}

void
bfin_uart_reschedule (struct hw *me)
{
  struct bfin_uart *uart = hw_data (me);

  if (uart->ier & ERBFI)
    {
      if (!uart->handler)
	uart->handler = hw_event_queue_schedule (me, 10000,
						 bfin_uart_poll, uart);
    }
  else
    {
      if (uart->handler)
	{
	  hw_event_queue_deschedule (me, uart->handler);
	  uart->handler = NULL;
	}
    }
}

bu16
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;
}

static unsigned
bfin_uart_io_write_buffer (struct hw *me, const void *source,
			   int space, address_word addr, unsigned nr_bytes)
{
  struct bfin_uart *uart = hw_data (me);
  bu32 mmr_off;
  bu32 value;
  bu16 *valuep;

  /* Invalid access mode is higher priority than missing register.  */
  if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true))
    return 0;

  value = dv_load_2 (source);
  mmr_off = addr - uart->base;
  valuep = (void *)((unsigned long)uart + mmr_base() + mmr_off);

  HW_TRACE_WRITE ();

  /* XXX: All MMRs are "8bit" ... what happens to high 8bits ?  */
  switch (mmr_off)
    {
    case mmr_offset(dll):
      if (uart->lcr & DLAB)
	uart->dll = value;
      else
	{
	  uart->thr = bfin_uart_write_byte (me, value, uart->mcr);

	  if (uart->ier & ETBEI)
	    hw_port_event (me, DV_PORT_TX, 1);
	}
      break;
    case mmr_offset(dlh):
      if (uart->lcr & DLAB)
	uart->dlh = value;
      else
	{
	  uart->ier = value;
	  bfin_uart_reschedule (me);
	}
      break;
    case mmr_offset(iir):
    case mmr_offset(lsr):
      /* XXX: Writes are ignored ?  */
      break;
    case mmr_offset(lcr):
    case mmr_offset(mcr):
    case mmr_offset(scr):
    case mmr_offset(gctl):
      *valuep = value;
      break;
    default:
      dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
      return 0;
    }

  return nr_bytes;
}

/* 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;
}

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 unsigned
bfin_uart_io_read_buffer (struct hw *me, void *dest,
			  int space, address_word addr, unsigned nr_bytes)
{
  struct bfin_uart *uart = hw_data (me);
  bu32 mmr_off;
  bu16 *valuep;

  /* Invalid access mode is higher priority than missing register.  */
  if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, false))
    return 0;

  mmr_off = addr - uart->base;
  valuep = (void *)((unsigned long)uart + mmr_base() + mmr_off);

  HW_TRACE_READ ();

  switch (mmr_off)
    {
    case mmr_offset(dll):
      if (uart->lcr & DLAB)
	dv_store_2 (dest, uart->dll);
      else
	{
	  uart->rbr = bfin_uart_get_next_byte (me, uart->rbr, uart->mcr, NULL);
	  dv_store_2 (dest, uart->rbr);
	}
      break;
    case mmr_offset(dlh):
      if (uart->lcr & DLAB)
	dv_store_2 (dest, uart->dlh);
      else
	dv_store_2 (dest, uart->ier);
      break;
    case mmr_offset(lsr):
      /* XXX: Reads are destructive on most parts, but not all ...  */
      uart->lsr |= bfin_uart_get_status (me);
      dv_store_2 (dest, *valuep);
      uart->lsr = 0;
      break;
    case mmr_offset(iir):
      /* XXX: Reads are destructive ...  */
    case mmr_offset(lcr):
    case mmr_offset(mcr):
    case mmr_offset(scr):
    case mmr_offset(gctl):
      dv_store_2 (dest, *valuep);
      break;
    default:
      dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
      return 0;
    }

  return nr_bytes;
}

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 unsigned
bfin_uart_dma_read_buffer (struct hw *me, void *dest, int space,
			   unsigned_word addr, unsigned nr_bytes)
{
  HW_TRACE_DMA_READ ();
  return bfin_uart_read_buffer (me, dest, nr_bytes);
}

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;
}

static unsigned
bfin_uart_dma_write_buffer (struct hw *me, const void *source,
			    int space, unsigned_word addr,
			    unsigned nr_bytes,
			    int violate_read_only_section)
{
  struct bfin_uart *uart = hw_data (me);
  unsigned ret;

  HW_TRACE_DMA_WRITE ();

  ret = bfin_uart_write_buffer (me, source, nr_bytes);

  if (ret == nr_bytes && (uart->ier & ETBEI))
    hw_port_event (me, DV_PORT_TX, 1);

  return ret;
}

static const struct hw_port_descriptor bfin_uart_ports[] =
{
  { "tx",   DV_PORT_TX,   0, output_port, },
  { "rx",   DV_PORT_RX,   0, output_port, },
  { "stat", DV_PORT_STAT, 0, output_port, },
  { NULL, 0, 0, 0, },
};

static void
attach_bfin_uart_regs (struct hw *me, struct bfin_uart *uart)
{
  address_word attach_address;
  int attach_space;
  unsigned attach_size;
  reg_property_spec reg;

  if (hw_find_property (me, "reg") == NULL)
    hw_abort (me, "Missing \"reg\" property");

  if (!hw_find_reg_array_property (me, "reg", 0, &reg))
    hw_abort (me, "\"reg\" property must contain three addr/size entries");

  hw_unit_address_to_attach_address (hw_parent (me),
				     &reg.address,
				     &attach_space, &attach_address, me);
  hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);

  if (attach_size != BFIN_MMR_UART_SIZE)
    hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_UART_SIZE);

  hw_attach_address (hw_parent (me),
		     0, attach_space, attach_address, attach_size, me);

  uart->base = attach_address;
}

static void
bfin_uart_finish (struct hw *me)
{
  struct bfin_uart *uart;

  uart = HW_ZALLOC (me, struct bfin_uart);

  set_hw_data (me, uart);
  set_hw_io_read_buffer (me, bfin_uart_io_read_buffer);
  set_hw_io_write_buffer (me, bfin_uart_io_write_buffer);
  set_hw_dma_read_buffer (me, bfin_uart_dma_read_buffer);
  set_hw_dma_write_buffer (me, bfin_uart_dma_write_buffer);
  set_hw_ports (me, bfin_uart_ports);

  attach_bfin_uart_regs (me, uart);

  /* Initialize the UART.  */
  uart->dll = 0x0001;
  uart->iir = 0x0001;
  uart->lsr = 0x0060;
}

const struct hw_descriptor dv_bfin_uart_descriptor[] =
{
  {"bfin_uart", bfin_uart_finish,},
  {NULL, NULL},
};
