Blame sim/mn10300/dv-mn103iop.c

Packit Service 706eca
/*  This file is part of the program GDB, the GNU debugger.
Packit Service 706eca
    
Packit Service 706eca
    Copyright (C) 1998-2018 Free Software Foundation, Inc.
Packit Service 706eca
    Contributed by Cygnus Solutions.
Packit Service 706eca
    
Packit Service 706eca
    This program is free software; you can redistribute it and/or modify
Packit Service 706eca
    it under the terms of the GNU General Public License as published by
Packit Service 706eca
    the Free Software Foundation; either version 3 of the License, or
Packit Service 706eca
    (at your option) any later version.
Packit Service 706eca
Packit Service 706eca
    This program is distributed in the hope that it will be useful,
Packit Service 706eca
    but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 706eca
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 706eca
    GNU General Public License for more details.
Packit Service 706eca
Packit Service 706eca
    You should have received a copy of the GNU General Public License
Packit Service 706eca
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
Packit Service 706eca
    
Packit Service 706eca
    */
Packit Service 706eca
Packit Service 706eca
#include "sim-main.h"
Packit Service 706eca
#include "hw-main.h"
Packit Service 706eca
Packit Service 706eca
/* DEVICE
Packit Service 706eca
Packit Service 706eca
   
Packit Service 706eca
   mn103iop - mn103002 I/O ports 0-3.
Packit Service 706eca
Packit Service 706eca
   
Packit Service 706eca
   DESCRIPTION
Packit Service 706eca
   
Packit Service 706eca
   Implements the mn103002 i/o ports as described in the mn103002 user guide.
Packit Service 706eca
Packit Service 706eca
Packit Service 706eca
   PROPERTIES   
Packit Service 706eca
Packit Service 706eca
   reg = <ioport-addr> <ioport-size> ...
Packit Service 706eca
Packit Service 706eca
Packit Service 706eca
   BUGS
Packit Service 706eca
Packit Service 706eca
   */
Packit Service 706eca
Packit Service 706eca
Packit Service 706eca
/* The I/O ports' registers' address block */
Packit Service 706eca
Packit Service 706eca
struct mn103iop_block {
Packit Service 706eca
  unsigned_word base;
Packit Service 706eca
  unsigned_word bound;
Packit Service 706eca
};
Packit Service 706eca
Packit Service 706eca
Packit Service 706eca
Packit Service 706eca
enum io_port_register_types {
Packit Service 706eca
  P0OUT,
Packit Service 706eca
  P1OUT,
Packit Service 706eca
  P2OUT,
Packit Service 706eca
  P3OUT,
Packit Service 706eca
  P0MD,
Packit Service 706eca
  P1MD,
Packit Service 706eca
  P2MD,
Packit Service 706eca
  P3MD,
Packit Service 706eca
  P2SS,
Packit Service 706eca
  P4SS,
Packit Service 706eca
  P0DIR,
Packit Service 706eca
  P1DIR,
Packit Service 706eca
  P2DIR,
Packit Service 706eca
  P3DIR,
Packit Service 706eca
  P0IN,
Packit Service 706eca
  P1IN,
Packit Service 706eca
  P2IN,
Packit Service 706eca
  P3IN,
Packit Service 706eca
};
Packit Service 706eca
Packit Service 706eca
#define NR_PORTS  4
Packit Service 706eca
Packit Service 706eca
enum {
Packit Service 706eca
  OUTPUT_BLOCK,
Packit Service 706eca
  MODE_BLOCK,
Packit Service 706eca
  DED_CTRL_BLOCK,
Packit Service 706eca
  CTRL_BLOCK,
Packit Service 706eca
  PIN_BLOCK,
Packit Service 706eca
  NR_BLOCKS
Packit Service 706eca
};
Packit Service 706eca
Packit Service 706eca
typedef struct _mn10300_ioport {
Packit Service 706eca
  unsigned8 output, output_mode, control, pin;
Packit Service 706eca
  struct hw_event *event;
Packit Service 706eca
} mn10300_ioport;
Packit Service 706eca
Packit Service 706eca
Packit Service 706eca
Packit Service 706eca
struct mn103iop {
Packit Service 706eca
  struct mn103iop_block block[NR_BLOCKS];
Packit Service 706eca
  mn10300_ioport port[NR_PORTS];
Packit Service 706eca
  unsigned8      p2ss, p4ss;
Packit Service 706eca
};
Packit Service 706eca
Packit Service 706eca
Packit Service 706eca
/* Finish off the partially created hw device.  Attach our local
Packit Service 706eca
   callbacks.  Wire up our port names etc */
Packit Service 706eca
Packit Service 706eca
static hw_io_read_buffer_method mn103iop_io_read_buffer;
Packit Service 706eca
static hw_io_write_buffer_method mn103iop_io_write_buffer;
Packit Service 706eca
Packit Service 706eca
static void
Packit Service 706eca
attach_mn103iop_regs (struct hw *me,
Packit Service 706eca
		      struct mn103iop *io_port)
Packit Service 706eca
{
Packit Service 706eca
  int i;
Packit Service 706eca
  unsigned_word attach_address;
Packit Service 706eca
  int attach_space;
Packit Service 706eca
  unsigned attach_size;
Packit Service 706eca
  reg_property_spec reg;
Packit Service 706eca
Packit Service 706eca
  if (hw_find_property (me, "reg") == NULL)
Packit Service 706eca
    hw_abort (me, "Missing \"reg\" property");
Packit Service 706eca
Packit Service 706eca
  for (i=0; i < NR_BLOCKS; ++i )
Packit Service 706eca
    {
Packit Service 706eca
      if (!hw_find_reg_array_property (me, "reg", i, &reg))
Packit Service 706eca
	hw_abort (me, "\"reg\" property must contain five addr/size entries");
Packit Service 706eca
      hw_unit_address_to_attach_address (hw_parent (me),
Packit Service 706eca
					 &reg.address,
Packit Service 706eca
					 &attach_space,
Packit Service 706eca
					 &attach_address,
Packit Service 706eca
					 me);
Packit Service 706eca
      io_port->block[i].base = attach_address;
Packit Service 706eca
      hw_unit_size_to_attach_size (hw_parent (me),
Packit Service 706eca
				   &reg.size,
Packit Service 706eca
				   &attach_size, me);
Packit Service 706eca
      io_port->block[i].bound = attach_address + (attach_size - 1);
Packit Service 706eca
      hw_attach_address (hw_parent (me),
Packit Service 706eca
			 0,
Packit Service 706eca
			 attach_space, attach_address, attach_size,
Packit Service 706eca
			 me);
Packit Service 706eca
    }
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
static void
Packit Service 706eca
mn103iop_finish (struct hw *me)
Packit Service 706eca
{
Packit Service 706eca
  struct mn103iop *io_port;
Packit Service 706eca
  int i;
Packit Service 706eca
Packit Service 706eca
  io_port = HW_ZALLOC (me, struct mn103iop);
Packit Service 706eca
  set_hw_data (me, io_port);
Packit Service 706eca
  set_hw_io_read_buffer (me, mn103iop_io_read_buffer);
Packit Service 706eca
  set_hw_io_write_buffer (me, mn103iop_io_write_buffer);
Packit Service 706eca
Packit Service 706eca
  /* Attach ourself to our parent bus */
Packit Service 706eca
  attach_mn103iop_regs (me, io_port);
Packit Service 706eca
Packit Service 706eca
  /* Initialize the i/o port registers. */
Packit Service 706eca
  for ( i=0; i
Packit Service 706eca
    {
Packit Service 706eca
      io_port->port[i].output = 0;
Packit Service 706eca
      io_port->port[i].output_mode = 0;
Packit Service 706eca
      io_port->port[i].control = 0;
Packit Service 706eca
      io_port->port[i].pin = 0;
Packit Service 706eca
    }
Packit Service 706eca
  io_port->port[2].output_mode = 0xff;
Packit Service 706eca
  io_port->p2ss = 0;
Packit Service 706eca
  io_port->p4ss = 0x0f;
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
Packit Service 706eca
/* read and write */
Packit Service 706eca
Packit Service 706eca
static int
Packit Service 706eca
decode_addr (struct hw *me,
Packit Service 706eca
	     struct mn103iop *io_port,
Packit Service 706eca
	     unsigned_word address)
Packit Service 706eca
{
Packit Service 706eca
  unsigned_word offset;
Packit Service 706eca
  offset = address - io_port->block[0].base;
Packit Service 706eca
  switch (offset)
Packit Service 706eca
    {
Packit Service 706eca
    case 0x00: return P0OUT;
Packit Service 706eca
    case 0x01: return P1OUT;
Packit Service 706eca
    case 0x04: return P2OUT;
Packit Service 706eca
    case 0x05: return P3OUT;
Packit Service 706eca
    case 0x20: return P0MD;
Packit Service 706eca
    case 0x21: return P1MD;
Packit Service 706eca
    case 0x24: return P2MD;
Packit Service 706eca
    case 0x25: return P3MD;
Packit Service 706eca
    case 0x44: return P2SS;
Packit Service 706eca
    case 0x48: return P4SS;
Packit Service 706eca
    case 0x60: return P0DIR;
Packit Service 706eca
    case 0x61: return P1DIR;
Packit Service 706eca
    case 0x64: return P2DIR;
Packit Service 706eca
    case 0x65: return P3DIR;
Packit Service 706eca
    case 0x80: return P0IN;
Packit Service 706eca
    case 0x81: return P1IN;
Packit Service 706eca
    case 0x84: return P2IN;
Packit Service 706eca
    case 0x85: return P3IN;
Packit Service 706eca
    default: 
Packit Service 706eca
      {
Packit Service 706eca
	hw_abort (me, "bad address");
Packit Service 706eca
	return -1;
Packit Service 706eca
      }
Packit Service 706eca
    }
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
Packit Service 706eca
static void
Packit Service 706eca
read_output_reg (struct hw *me,
Packit Service 706eca
		 struct mn103iop *io_port,
Packit Service 706eca
		 unsigned_word io_port_reg,
Packit Service 706eca
		 const void *dest,
Packit Service 706eca
		 unsigned  nr_bytes)
Packit Service 706eca
{
Packit Service 706eca
  if ( nr_bytes == 1 )
Packit Service 706eca
    {
Packit Service 706eca
      *(unsigned8 *)dest = io_port->port[io_port_reg].output;
Packit Service 706eca
    }
Packit Service 706eca
  else
Packit Service 706eca
    {
Packit Service 706eca
      hw_abort (me, "bad read size of %d bytes from P%dOUT.", nr_bytes, 
Packit Service 706eca
		io_port_reg);
Packit Service 706eca
    }
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
Packit Service 706eca
static void
Packit Service 706eca
read_output_mode_reg (struct hw *me,
Packit Service 706eca
		      struct mn103iop *io_port,
Packit Service 706eca
		      unsigned_word io_port_reg,
Packit Service 706eca
		      const void *dest,
Packit Service 706eca
		      unsigned  nr_bytes)
Packit Service 706eca
{
Packit Service 706eca
  if ( nr_bytes == 1 )
Packit Service 706eca
    {
Packit Service 706eca
      /* check if there are fields which can't be written and
Packit Service 706eca
	 take appropriate action depending what bits are set */
Packit Service 706eca
      *(unsigned8 *)dest = io_port->port[io_port_reg].output_mode;
Packit Service 706eca
    }
Packit Service 706eca
  else
Packit Service 706eca
    {
Packit Service 706eca
      hw_abort (me, "bad read size of %d bytes to P%dMD.", nr_bytes, 
Packit Service 706eca
		io_port_reg);
Packit Service 706eca
    }
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
Packit Service 706eca
static void
Packit Service 706eca
read_control_reg (struct hw *me,
Packit Service 706eca
		  struct mn103iop *io_port,
Packit Service 706eca
		  unsigned_word io_port_reg,
Packit Service 706eca
		  const void *dest,
Packit Service 706eca
		  unsigned  nr_bytes)
Packit Service 706eca
{
Packit Service 706eca
  if ( nr_bytes == 1 )
Packit Service 706eca
    {
Packit Service 706eca
      *(unsigned8 *)dest = io_port->port[io_port_reg].control;
Packit Service 706eca
    }
Packit Service 706eca
  else
Packit Service 706eca
    {
Packit Service 706eca
      hw_abort (me, "bad read size of %d bytes to P%dDIR.", nr_bytes, 
Packit Service 706eca
		io_port_reg);
Packit Service 706eca
    }
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
Packit Service 706eca
static void
Packit Service 706eca
read_pin_reg (struct hw *me,
Packit Service 706eca
	      struct mn103iop *io_port,
Packit Service 706eca
	      unsigned_word io_port_reg,
Packit Service 706eca
	      const void *dest,
Packit Service 706eca
	      unsigned  nr_bytes)
Packit Service 706eca
{
Packit Service 706eca
  if ( nr_bytes == 1 )
Packit Service 706eca
    {
Packit Service 706eca
      *(unsigned8 *)dest = io_port->port[io_port_reg].pin;
Packit Service 706eca
    }
Packit Service 706eca
  else
Packit Service 706eca
    {
Packit Service 706eca
      hw_abort (me, "bad read size of %d bytes to P%dIN.", nr_bytes, 
Packit Service 706eca
		io_port_reg);
Packit Service 706eca
    }
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
Packit Service 706eca
static void
Packit Service 706eca
read_dedicated_control_reg (struct hw *me,
Packit Service 706eca
			    struct mn103iop *io_port,
Packit Service 706eca
			    unsigned_word io_port_reg,
Packit Service 706eca
			    const void *dest,
Packit Service 706eca
			    unsigned  nr_bytes)
Packit Service 706eca
{
Packit Service 706eca
  if ( nr_bytes == 1 )
Packit Service 706eca
    {
Packit Service 706eca
      /* select on io_port_reg: */
Packit Service 706eca
      if ( io_port_reg == P2SS )
Packit Service 706eca
	{
Packit Service 706eca
	  *(unsigned8 *)dest = io_port->p2ss;
Packit Service 706eca
	}
Packit Service 706eca
      else
Packit Service 706eca
	{
Packit Service 706eca
	  *(unsigned8 *)dest = io_port->p4ss;
Packit Service 706eca
	}
Packit Service 706eca
    }
Packit Service 706eca
  else
Packit Service 706eca
    {
Packit Service 706eca
      hw_abort (me, "bad read size of %d bytes to PSS.", nr_bytes); 
Packit Service 706eca
    }
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
Packit Service 706eca
static unsigned
Packit Service 706eca
mn103iop_io_read_buffer (struct hw *me,
Packit Service 706eca
			 void *dest,
Packit Service 706eca
			 int space,
Packit Service 706eca
			 unsigned_word base,
Packit Service 706eca
			 unsigned nr_bytes)
Packit Service 706eca
{
Packit Service 706eca
  struct mn103iop *io_port = hw_data (me);
Packit Service 706eca
  enum io_port_register_types io_port_reg;
Packit Service 706eca
  HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));
Packit Service 706eca
Packit Service 706eca
  io_port_reg = decode_addr (me, io_port, base);
Packit Service 706eca
  switch (io_port_reg)
Packit Service 706eca
    {
Packit Service 706eca
    /* Port output registers */
Packit Service 706eca
    case P0OUT:
Packit Service 706eca
    case P1OUT:
Packit Service 706eca
    case P2OUT:
Packit Service 706eca
    case P3OUT:
Packit Service 706eca
      read_output_reg(me, io_port, io_port_reg-P0OUT, dest, nr_bytes);
Packit Service 706eca
      break;
Packit Service 706eca
Packit Service 706eca
    /* Port output mode registers */
Packit Service 706eca
    case P0MD:
Packit Service 706eca
    case P1MD:
Packit Service 706eca
    case P2MD:
Packit Service 706eca
    case P3MD:
Packit Service 706eca
      read_output_mode_reg(me, io_port, io_port_reg-P0MD, dest, nr_bytes);
Packit Service 706eca
      break;
Packit Service 706eca
Packit Service 706eca
    /* Port control registers */
Packit Service 706eca
    case P0DIR:
Packit Service 706eca
    case P1DIR:
Packit Service 706eca
    case P2DIR:
Packit Service 706eca
    case P3DIR:
Packit Service 706eca
      read_control_reg(me, io_port, io_port_reg-P0DIR, dest, nr_bytes);
Packit Service 706eca
      break;
Packit Service 706eca
Packit Service 706eca
    /* Port pin registers */
Packit Service 706eca
    case P0IN:
Packit Service 706eca
    case P1IN:
Packit Service 706eca
    case P2IN:
Packit Service 706eca
      read_pin_reg(me, io_port, io_port_reg-P0IN, dest, nr_bytes);
Packit Service 706eca
      break;
Packit Service 706eca
Packit Service 706eca
    case P2SS:
Packit Service 706eca
    case P4SS:
Packit Service 706eca
      read_dedicated_control_reg(me, io_port, io_port_reg, dest, nr_bytes);
Packit Service 706eca
      break;
Packit Service 706eca
Packit Service 706eca
    default:
Packit Service 706eca
      hw_abort(me, "invalid address");
Packit Service 706eca
    }
Packit Service 706eca
Packit Service 706eca
  return nr_bytes;
Packit Service 706eca
}     
Packit Service 706eca
Packit Service 706eca
Packit Service 706eca
static void
Packit Service 706eca
write_output_reg (struct hw *me,
Packit Service 706eca
		  struct mn103iop *io_port,
Packit Service 706eca
		  unsigned_word io_port_reg,
Packit Service 706eca
		  const void *source,
Packit Service 706eca
		  unsigned  nr_bytes)
Packit Service 706eca
{
Packit Service 706eca
  unsigned8 buf = *(unsigned8 *)source;
Packit Service 706eca
  if ( nr_bytes == 1 )
Packit Service 706eca
    {
Packit Service 706eca
      if ( io_port_reg == 3 && (buf & 0xfc) != 0 )
Packit Service 706eca
	{
Packit Service 706eca
	  hw_abort(me, "Cannot write to read-only bits of P3OUT.");
Packit Service 706eca
	}
Packit Service 706eca
      else
Packit Service 706eca
	{
Packit Service 706eca
	  io_port->port[io_port_reg].output = buf;
Packit Service 706eca
	}
Packit Service 706eca
    }
Packit Service 706eca
  else
Packit Service 706eca
    {
Packit Service 706eca
      hw_abort (me, "bad read size of %d bytes from P%dOUT.", nr_bytes, 
Packit Service 706eca
		io_port_reg);
Packit Service 706eca
    }
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
Packit Service 706eca
static void
Packit Service 706eca
write_output_mode_reg (struct hw *me,
Packit Service 706eca
		       struct mn103iop *io_port,
Packit Service 706eca
		       unsigned_word io_port_reg,
Packit Service 706eca
		       const void *source,
Packit Service 706eca
		       unsigned  nr_bytes)
Packit Service 706eca
{
Packit Service 706eca
  unsigned8 buf = *(unsigned8 *)source;
Packit Service 706eca
  if ( nr_bytes == 1 )
Packit Service 706eca
    {
Packit Service 706eca
      /* check if there are fields which can't be written and
Packit Service 706eca
	 take appropriate action depending what bits are set */
Packit Service 706eca
      if ( ( io_port_reg == 3 && (buf & 0xfc) != 0 )
Packit Service 706eca
	   || ( (io_port_reg == 0 || io_port_reg == 1)  && (buf & 0xfe) != 0 ) )
Packit Service 706eca
	{
Packit Service 706eca
	  hw_abort(me, "Cannot write to read-only bits of output mode register.");
Packit Service 706eca
	}
Packit Service 706eca
      else
Packit Service 706eca
	{
Packit Service 706eca
	  io_port->port[io_port_reg].output_mode = buf;
Packit Service 706eca
	}
Packit Service 706eca
    }
Packit Service 706eca
  else
Packit Service 706eca
    {
Packit Service 706eca
      hw_abort (me, "bad write size of %d bytes to P%dMD.", nr_bytes, 
Packit Service 706eca
		io_port_reg);
Packit Service 706eca
    }
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
Packit Service 706eca
static void
Packit Service 706eca
write_control_reg (struct hw *me,
Packit Service 706eca
		   struct mn103iop *io_port,
Packit Service 706eca
		   unsigned_word io_port_reg,
Packit Service 706eca
		   const void *source,
Packit Service 706eca
		   unsigned  nr_bytes)
Packit Service 706eca
{
Packit Service 706eca
  unsigned8 buf = *(unsigned8 *)source;
Packit Service 706eca
  if ( nr_bytes == 1 )
Packit Service 706eca
    {
Packit Service 706eca
      if ( io_port_reg == 3 && (buf & 0xfc) != 0 )
Packit Service 706eca
	{
Packit Service 706eca
	  hw_abort(me, "Cannot write to read-only bits of P3DIR.");
Packit Service 706eca
	}
Packit Service 706eca
      else
Packit Service 706eca
	{
Packit Service 706eca
	  io_port->port[io_port_reg].control = buf;
Packit Service 706eca
	}
Packit Service 706eca
    }
Packit Service 706eca
  else
Packit Service 706eca
    {
Packit Service 706eca
      hw_abort (me, "bad write size of %d bytes to P%dDIR.", nr_bytes, 
Packit Service 706eca
		io_port_reg);
Packit Service 706eca
    }
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
Packit Service 706eca
static void
Packit Service 706eca
write_dedicated_control_reg (struct hw *me,
Packit Service 706eca
			     struct mn103iop *io_port,
Packit Service 706eca
			     unsigned_word io_port_reg,
Packit Service 706eca
			     const void *source,
Packit Service 706eca
			     unsigned  nr_bytes)
Packit Service 706eca
{
Packit Service 706eca
  unsigned8 buf = *(unsigned8 *)source;
Packit Service 706eca
  if ( nr_bytes == 1 )
Packit Service 706eca
    {
Packit Service 706eca
      /* select on io_port_reg: */
Packit Service 706eca
      if ( io_port_reg == P2SS )
Packit Service 706eca
	{
Packit Service 706eca
	  if ( (buf & 0xfc)  != 0 )
Packit Service 706eca
	    {
Packit Service 706eca
	      hw_abort(me, "Cannot write to read-only bits in p2ss.");
Packit Service 706eca
	    }
Packit Service 706eca
	  else
Packit Service 706eca
	    {
Packit Service 706eca
	      io_port->p2ss = buf;
Packit Service 706eca
	    }
Packit Service 706eca
	}
Packit Service 706eca
      else
Packit Service 706eca
	{
Packit Service 706eca
	  if ( (buf & 0xf0) != 0 )
Packit Service 706eca
	    {
Packit Service 706eca
	      hw_abort(me, "Cannot write to read-only bits in p4ss.");
Packit Service 706eca
	    }
Packit Service 706eca
	  else
Packit Service 706eca
	    {
Packit Service 706eca
	      io_port->p4ss = buf;
Packit Service 706eca
	    }
Packit Service 706eca
	}
Packit Service 706eca
    }
Packit Service 706eca
  else
Packit Service 706eca
    {
Packit Service 706eca
      hw_abort (me, "bad write size of %d bytes to PSS.", nr_bytes); 
Packit Service 706eca
    }
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
Packit Service 706eca
static unsigned
Packit Service 706eca
mn103iop_io_write_buffer (struct hw *me,
Packit Service 706eca
			  const void *source,
Packit Service 706eca
			  int space,
Packit Service 706eca
			  unsigned_word base,
Packit Service 706eca
			  unsigned nr_bytes)
Packit Service 706eca
{
Packit Service 706eca
  struct mn103iop *io_port = hw_data (me);
Packit Service 706eca
  enum io_port_register_types io_port_reg;
Packit Service 706eca
  HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes));
Packit Service 706eca
Packit Service 706eca
  io_port_reg = decode_addr (me, io_port, base);
Packit Service 706eca
  switch (io_port_reg)
Packit Service 706eca
    {
Packit Service 706eca
    /* Port output registers */
Packit Service 706eca
    case P0OUT:
Packit Service 706eca
    case P1OUT:
Packit Service 706eca
    case P2OUT:
Packit Service 706eca
    case P3OUT:
Packit Service 706eca
      write_output_reg(me, io_port, io_port_reg-P0OUT, source, nr_bytes);
Packit Service 706eca
      break;
Packit Service 706eca
Packit Service 706eca
    /* Port output mode registers */
Packit Service 706eca
    case P0MD:
Packit Service 706eca
    case P1MD:
Packit Service 706eca
    case P2MD:
Packit Service 706eca
    case P3MD:
Packit Service 706eca
      write_output_mode_reg(me, io_port, io_port_reg-P0MD, source, nr_bytes);
Packit Service 706eca
      break;
Packit Service 706eca
Packit Service 706eca
    /* Port control registers */
Packit Service 706eca
    case P0DIR:
Packit Service 706eca
    case P1DIR:
Packit Service 706eca
    case P2DIR:
Packit Service 706eca
    case P3DIR:
Packit Service 706eca
      write_control_reg(me, io_port, io_port_reg-P0DIR, source, nr_bytes);
Packit Service 706eca
      break;
Packit Service 706eca
Packit Service 706eca
    /* Port pin registers */
Packit Service 706eca
    case P0IN:
Packit Service 706eca
    case P1IN:
Packit Service 706eca
    case P2IN:
Packit Service 706eca
      hw_abort(me, "Cannot write to pin register.");
Packit Service 706eca
      break;
Packit Service 706eca
Packit Service 706eca
    case P2SS:
Packit Service 706eca
    case P4SS:
Packit Service 706eca
      write_dedicated_control_reg(me, io_port, io_port_reg, source, nr_bytes);
Packit Service 706eca
      break;
Packit Service 706eca
Packit Service 706eca
    default:
Packit Service 706eca
      hw_abort(me, "invalid address");
Packit Service 706eca
    }
Packit Service 706eca
Packit Service 706eca
  return nr_bytes;
Packit Service 706eca
}     
Packit Service 706eca
Packit Service 706eca
Packit Service 706eca
const struct hw_descriptor dv_mn103iop_descriptor[] = {
Packit Service 706eca
  { "mn103iop", mn103iop_finish, },
Packit Service 706eca
  { NULL },
Packit Service 706eca
};