/*  This file is part of the program GDB, the GNU debugger.
    
    Copyright (C) 1998, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
    Contributed by Cygnus Solutions.
    
    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/>.
    
    */

#include "sim-main.h"
#include "hw-main.h"
#include "dv-sockser.h"


/* DEVICE

   
   mn103ser - mn103002 serial devices 0, 1 and 2.

   
   DESCRIPTION
   
   Implements the mn103002 serial interfaces as described in the
   mn103002 user guide. 


   PROPERTIES   

   reg = <serial-addr> <serial-size>


   BUGS

   */


/* The serial devices' registers' address block */

struct mn103ser_block {
  unsigned_word base;
  unsigned_word bound;
};



enum serial_register_types {
    SC0CTR,
    SC1CTR,
    SC2CTR,
    SC0ICR,
    SC1ICR,
    SC2ICR,
    SC0TXB,
    SC1TXB,
    SC2TXB,
    SC0RXB,
    SC1RXB,
    SC2RXB,
    SC0STR,
    SC1STR,
    SC2STR,
    SC2TIM,
};


#define NR_SERIAL_DEVS  3
#define SIO_STAT_RRDY 0x0010

typedef struct _mn10300_serial {
  unsigned16 status, control;
  unsigned8  txb, rxb, intmode;
  struct hw_event *event;
} mn10300_serial;



struct mn103ser {
  struct mn103ser_block block;
  mn10300_serial device[NR_SERIAL_DEVS];
  unsigned8      serial2_timer_reg;
  do_hw_poll_read_method *reader;
};

/* output port ID's */

/* for mn103002 */
enum {
  SERIAL0_RECEIVE,
  SERIAL1_RECEIVE,
  SERIAL2_RECEIVE,
  SERIAL0_SEND,
  SERIAL1_SEND,
  SERIAL2_SEND,
};


static const struct hw_port_descriptor mn103ser_ports[] = {

  { "serial-0-receive",  SERIAL0_RECEIVE, 0, output_port, },
  { "serial-1-receive",  SERIAL1_RECEIVE, 0, output_port, },
  { "serial-2-receive",  SERIAL2_RECEIVE, 0, output_port, },
  { "serial-0-transmit", SERIAL0_SEND, 0, output_port, },
  { "serial-1-transmit", SERIAL1_SEND, 0, output_port, },
  { "serial-2-transmit", SERIAL2_SEND, 0, output_port, },

  { NULL, },
};



/* Finish off the partially created hw device.  Attach our local
   callbacks.  Wire up our port names etc */

static hw_io_read_buffer_method mn103ser_io_read_buffer;
static hw_io_write_buffer_method mn103ser_io_write_buffer;

static void
attach_mn103ser_regs (struct hw *me,
		      struct mn103ser *serial)
{
  unsigned_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);
  serial->block.base = attach_address;
  hw_unit_size_to_attach_size (hw_parent (me),
			       &reg.size,
			       &attach_size, me);
  serial->block.bound = attach_address + (attach_size - 1);
  hw_attach_address (hw_parent (me),
		     0,
		     attach_space, attach_address, attach_size,
		     me);
}

static void
mn103ser_finish (struct hw *me)
{
  struct mn103ser *serial;
  int i;

  serial = HW_ZALLOC (me, struct mn103ser);
  set_hw_data (me, serial);
  set_hw_io_read_buffer (me, mn103ser_io_read_buffer);
  set_hw_io_write_buffer (me, mn103ser_io_write_buffer);
  set_hw_ports (me, mn103ser_ports);

  /* Attach ourself to our parent bus */
  attach_mn103ser_regs (me, serial);

  /* If so configured, enable polled input */
  if (hw_find_property (me, "poll?") != NULL
      && hw_find_boolean_property (me, "poll?"))
    {
      serial->reader = sim_io_poll_read;
    }
  else
    {
      serial->reader = sim_io_read;
    }

  /* Initialize the serial device registers. */
  for ( i=0; i<NR_SERIAL_DEVS; ++i )
    {
      serial->device[i].txb = 0;
      serial->device[i].rxb = 0;
      serial->device[i].status = 0;
      serial->device[i].control = 0;
      serial->device[i].intmode = 0;
      serial->device[i].event = NULL;
    }
}


/* read and write */

static int
decode_addr (struct hw *me,
	     struct mn103ser *serial,
	     unsigned_word address)
{
  unsigned_word offset;
  offset = address - serial->block.base;
  switch (offset)
    {
    case 0x00: return SC0CTR;
    case 0x04: return SC0ICR;
    case 0x08: return SC0TXB;
    case 0x09: return SC0RXB;
    case 0x0C: return SC0STR;
    case 0x10: return SC1CTR;
    case 0x14: return SC1ICR;
    case 0x18: return SC1TXB;
    case 0x19: return SC1RXB;
    case 0x1C: return SC1STR;
    case 0x20: return SC2CTR;
    case 0x24: return SC2ICR;
    case 0x28: return SC2TXB;
    case 0x29: return SC2RXB;
    case 0x2C: return SC2STR;
    case 0x2D: return SC2TIM;
    default: 
      {
	hw_abort (me, "bad address");
	return -1;
      }
    }
}

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

}

static void
read_control_reg (struct hw *me,
		  struct mn103ser *serial,
		  unsigned_word serial_reg,
		  void *dest,
		  unsigned  nr_bytes)
{
  /* really allow 1 byte read, too */
  if ( nr_bytes == 2 )
    {
      *(unsigned16 *)dest = H2LE_2 (serial->device[serial_reg].control);
    }
  else
    {
      hw_abort (me, "bad read size of %d bytes from SC%dCTR.", nr_bytes, 
		serial_reg);
    }
}


static void
read_intmode_reg (struct hw *me,
		  struct mn103ser *serial,
		  unsigned_word serial_reg,
		  void *dest,
		  unsigned  nr_bytes)
{
  if ( nr_bytes == 1 )
    {
      *(unsigned8 *)dest = serial->device[serial_reg].intmode;
    }
  else
    {
      hw_abort (me, "bad read size of %d bytes from SC%dICR.", nr_bytes, 
		serial_reg);
    }
}


static void
read_txb (struct hw *me,
	  struct mn103ser *serial,
	  unsigned_word serial_reg,
	  void *dest,
	  unsigned  nr_bytes)
{
  if ( nr_bytes == 1 )
    {
      *(unsigned8 *)dest = serial->device[serial_reg].txb;
    }
  else
    {
      hw_abort (me, "bad read size of %d bytes from SC%dTXB.", nr_bytes, 
		serial_reg);
    }
}


static void
read_rxb (struct hw *me,
	  struct mn103ser *serial,
	  unsigned_word serial_reg,
	  void *dest,
	  unsigned  nr_bytes)
{
  if ( nr_bytes == 1 )
    {
      *(unsigned8 *)dest = serial->device[serial_reg].rxb;
      /* Reception buffer is now empty. */
      serial->device[serial_reg].status &= ~SIO_STAT_RRDY;
    }
  else
    {
      hw_abort (me, "bad read size of %d bytes from SC%dRXB.", nr_bytes, 
		serial_reg);
    }
}


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


static void
read_serial2_timer_reg (struct hw *me,
			struct mn103ser *serial,
			void *dest,
			unsigned  nr_bytes)
{
  if ( nr_bytes == 1 )
    {
      * (unsigned8 *) dest = (unsigned8) serial->serial2_timer_reg;
    }
  else
    {
      hw_abort (me, "bad read size of %d bytes to SC2TIM.", nr_bytes);
    }
}


static unsigned
mn103ser_io_read_buffer (struct hw *me,
			 void *dest,
			 int space,
			 unsigned_word base,
			 unsigned nr_bytes)
{
  struct mn103ser *serial = hw_data (me);
  enum serial_register_types serial_reg;
  HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));

  serial_reg = decode_addr (me, serial, base);
  switch (serial_reg)
    {
    /* control registers */
    case SC0CTR:
    case SC1CTR:
    case SC2CTR:
      read_control_reg(me, serial, serial_reg-SC0CTR, dest, nr_bytes);
      HW_TRACE ((me, "read - ctrl reg%d has 0x%x\n", serial_reg-SC0CTR,
		 *(unsigned8 *)dest));
      break;

    /* interrupt mode registers */
    case SC0ICR:
    case SC1ICR:
    case SC2ICR:
      read_intmode_reg(me, serial, serial_reg-SC0ICR, dest, nr_bytes);
      HW_TRACE ((me, "read - intmode reg%d has 0x%x\n", serial_reg-SC0ICR,
		 *(unsigned8 *)dest));
      break;

    /* transmission buffers */
    case SC0TXB:
    case SC1TXB:
    case SC2TXB:
      read_txb(me, serial, serial_reg-SC0TXB, dest, nr_bytes);
      HW_TRACE ((me, "read - txb%d has %c\n", serial_reg-SC0TXB,
		 *(char *)dest));
      break;

    /* reception buffers */
    case SC0RXB: 
    case SC1RXB:
    case SC2RXB:
      read_rxb(me, serial, serial_reg-SC0RXB, dest, nr_bytes);
      HW_TRACE ((me, "read - rxb%d has %c\n", serial_reg-SC0RXB,
		 *(char *)dest));
     break;

    /* status registers */
    case SC0STR: 
    case SC1STR: 
    case SC2STR: 
      read_status_reg(me, serial, serial_reg-SC0STR, dest, nr_bytes);
      HW_TRACE ((me, "read - status reg%d has 0x%x\n", serial_reg-SC0STR,
		 *(unsigned8 *)dest));
      break;

    case SC2TIM:
      read_serial2_timer_reg(me, serial, dest, nr_bytes);
      HW_TRACE ((me, "read - serial2 timer reg %d\n", *(unsigned8 *)dest));
      break;

    default:
      hw_abort(me, "invalid address");
    }

  return nr_bytes;
}     


static void
write_control_reg (struct hw *me,
		   struct mn103ser *serial,
		   unsigned_word serial_reg,
		   const void *source,
		   unsigned  nr_bytes)
{
  unsigned16 val = LE2H_2 (*(unsigned16 *)source);

  /* really allow 1 byte write, too */
  if ( nr_bytes == 2 )
    {
      if ( serial_reg == 2 && (val & 0x0C04) != 0 )
	{
	  hw_abort(me, "Cannot write to read-only bits of SC2CTR.");
	}
      else
	{
	  serial->device[serial_reg].control = val;
	}
    }
  else
    {
      hw_abort (me, "bad read size of %d bytes from SC%dSTR.", nr_bytes, 
		serial_reg);
    }
}


static void
write_intmode_reg (struct hw *me,
		   struct mn103ser *serial,
		   unsigned_word serial_reg,
		   const void *source,
		   unsigned  nr_bytes)
{
unsigned8 val = *(unsigned8 *)source;

  if ( nr_bytes == 1 )
    {
      /* Check for attempt to write to read-only bits of register. */
      if ( ( serial_reg == 2 && (val & 0xCA) != 0 )
	   || ( serial_reg != 2 && (val & 0x4A) != 0 ) )
	{
	  hw_abort(me, "Cannot write to read-only bits of SC%dICR.",
		   serial_reg);
	}
      else
	{
	  serial->device[serial_reg].intmode = val;
	}
    }
  else
    {
      hw_abort (me, "bad write size of %d bytes to SC%dICR.", nr_bytes, 
		serial_reg);
    }
}


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
write_serial2_timer_reg (struct hw *me,
			 struct mn103ser *serial,
			 const void *source,
			 unsigned  nr_bytes)
{
  if ( nr_bytes == 1 )
    {
      serial->serial2_timer_reg = *(unsigned8 *)source;
    }
  else
    {
      hw_abort (me, "bad write size of %d bytes to SC2TIM.", nr_bytes); 
    }
}


static unsigned
mn103ser_io_write_buffer (struct hw *me,
			  const void *source,
			  int space,
			  unsigned_word base,
			  unsigned nr_bytes)
{
  struct mn103ser *serial = hw_data (me);
  enum serial_register_types serial_reg;
  HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes));

  serial_reg = decode_addr (me, serial, base);
  switch (serial_reg)
    {
    /* control registers */
    case SC0CTR:
    case SC1CTR:
    case SC2CTR:
      HW_TRACE ((me, "write - ctrl reg%d has 0x%x, nrbytes=%d.\n",
		 serial_reg-SC0CTR, *(unsigned8 *)source, nr_bytes));
      write_control_reg(me, serial, serial_reg-SC0CTR, source, nr_bytes);
      break;

    /* interrupt mode registers */
    case SC0ICR:
    case SC1ICR:
    case SC2ICR:
      HW_TRACE ((me, "write - intmode reg%d has 0x%x, nrbytes=%d.\n",
		 serial_reg-SC0ICR, *(unsigned8 *)source, nr_bytes));
      write_intmode_reg(me, serial, serial_reg-SC0ICR, source, nr_bytes);
      break;

    /* transmission buffers */
    case SC0TXB:
    case SC1TXB:
    case SC2TXB:
      HW_TRACE ((me, "write - txb%d has %c, nrbytes=%d.\n",
		 serial_reg-SC0TXB, *(char *)source, nr_bytes));
      write_txb(me, serial, serial_reg-SC0TXB, source, nr_bytes);
      break;

    /* reception buffers */
    case SC0RXB: 
    case SC1RXB:
    case SC2RXB:
      hw_abort(me, "Cannot write to reception buffer.");
     break;

    /* status registers */
    case SC0STR: 
    case SC1STR: 
    case SC2STR: 
      hw_abort(me, "Cannot write to status register.");
      break;

    case SC2TIM:
      HW_TRACE ((me, "read - serial2 timer reg %d (nrbytes=%d)\n",
		 *(unsigned8 *)source, nr_bytes));
      write_serial2_timer_reg(me, serial, source, nr_bytes);
      break;

    default:
      hw_abort(me, "invalid address");
    }

  return nr_bytes;
}     


const struct hw_descriptor dv_mn103ser_descriptor[] = {
  { "mn103ser", mn103ser_finish, },
  { NULL },
};
