/*  This file is part of the program psim.
    
    Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au>
    
    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/>.
    
    */


#ifndef _HW_GLUE_C_
#define _HW_GLUE_C_

#include "device_table.h"


/* DEVICE
   

   glue - glue to interconnect and test interrupts
   

   DESCRIPTION
   

   The glue device provides two functions.  Firstly, it provides a
   mechanism for inspecting and driving the interrupt net.  Secondly,
   it provides a set of boolean primitives that can be used add
   combinatorial operations to the interrupt network.

   Glue devices have a variable number of big endian <<output>>
   registers.  Each host-word size.  The registers can be both read
   and written.

   Writing a value to an output register causes an interrupt (of the
   specified level) to be driven on the devices corresponding output
   interrupt port.

   Reading an <<output>> register returns either the last value
   written or the most recently computed value (for that register) as
   a result of an interrupt ariving (which ever was computed last).

   At present the following sub device types are available:

   <<glue>>: In addition to driving its output interrupt port with any
   value written to an interrupt input port is stored in the
   corresponding <<output>> register.  Such input interrupts, however,
   are not propogated to an output interrupt port.

   <<glue-and>>: The bit-wise AND of the interrupt inputs is computed
   and then both stored in <<output>> register zero and propogated to
   output interrupt output port zero.


   PROPERTIES
   

   reg = <address> <size> (required)

   Specify the address (within the parent bus) that this device is to
   live.  The address must be 2048 * sizeof(word) (8k in a 32bit
   simulation) aligned.


   interrupt-ranges = <int-number> <range> (optional)

   If present, this specifies the number of valid interrupt inputs (up
   to the maximum of 2048).  By default, <<int-number>> is zero and
   range is determined by the <<reg>> size.


   EXAMPLES


   Enable tracing of the device:

   | -t glue-device \


   Create source, bitwize-and, and sink glue devices.  Since the
   device at address <<0x10000>> is of size <<8>> it will have two
   output interrupt ports.

   | -o '/iobus@0xf0000000/glue@0x10000/reg 0x10000 8' \
   | -o '/iobus@0xf0000000/glue-and@0x20000/reg 0x20000 4' \
   | -o '/iobus@0xf0000000/glue-and/interrupt-ranges 0 2' \
   | -o '/iobus@0xf0000000/glue@0x30000/reg 0x30000 4' \


   Wire the two source interrupts to the AND device:

   | -o '/iobus@0xf0000000/glue@0x10000 > 0 0 /iobus/glue-and' \
   | -o '/iobus@0xf0000000/glue@0x10000 > 1 1 /iobus/glue-and' \


   Wire the AND device up to the sink so that the and's output is not
   left open.

   | -o '/iobus@0xf0000000/glue-and > 0 0 /iobus/glue@0x30000' \


   With the above configuration.  The client program is able to
   compute a two bit AND.  For instance the <<C>> stub below prints 1
   AND 0.

   |  unsigned *input = (void*)0xf0010000;
   |  unsigned *output = (void*)0xf0030000;
   |  unsigned ans;
   |  input[0] = htonl(1);
   |  input[1] = htonl(0);
   |  ans = ntohl(*output);
   |  write_string("AND is ");
   |  write_int(ans);
   |  write_line();
   

   BUGS

   
   A future implementation of this device may support multiple
   interrupt ranges.

   Some of the devices listed may not yet be fully implemented.

   Additional devices such as a dff, an inverter or a latch may be
   useful.

   */


enum {
  max_nr_interrupts = 2048,
};

typedef enum _hw_glue_type {
  glue_undefined = 0,
  glue_io,
  glue_and,
  glue_nand,
  glue_or,
  glue_xor,
  glue_nor,
  glue_not,
} hw_glue_type;

typedef struct _hw_glue_device {
  hw_glue_type type;
  int int_number;
  int *input;
  int nr_inputs;
  unsigned sizeof_input;
  /* our output registers */
  int space;
  unsigned_word address;
  unsigned sizeof_output;
  int *output;
  int nr_outputs;
} hw_glue_device;


static void
hw_glue_init_address(device *me)
{
  hw_glue_device *glue = (hw_glue_device*)device_data(me);

  /* attach to my parent */
  generic_device_init_address(me);

  /* establish the output registers */
  if (glue->output != NULL) {
    memset(glue->output, 0, glue->sizeof_output);
  }
  else {
    reg_property_spec unit;
    int reg_nr;
    /* find a relevant reg entry */
    reg_nr = 0;
    while (device_find_reg_array_property(me, "reg", reg_nr, &unit)
	   && !device_size_to_attach_size(device_parent(me), &unit.size,
					  &glue->sizeof_output, me))
      reg_nr++;
    /* check out the size */
    if (glue->sizeof_output == 0)
      device_error(me, "at least one reg property size must be nonzero");
    if (glue->sizeof_output % sizeof(unsigned_word) != 0)
      device_error(me, "reg property size must be %zu aligned", sizeof(unsigned_word));
    /* and the address */
    device_address_to_attach_address(device_parent(me),
				     &unit.address, &glue->space, &glue->address,
				     me);
    if (glue->address % (sizeof(unsigned_word) * max_nr_interrupts) != 0)
      device_error(me, "reg property address must be %zu aligned",
		   sizeof(unsigned_word) * max_nr_interrupts);
    glue->nr_outputs = glue->sizeof_output / sizeof(unsigned_word);
    glue->output = zalloc(glue->sizeof_output);
  }

  /* establish the input interrupt ports */
  if (glue->input != NULL) {
    memset(glue->input, 0, glue->sizeof_input);
  }
  else {
    const device_property *ranges = device_find_property(me, "interrupt-ranges");
    if (ranges == NULL) {
      glue->int_number = 0;
      glue->nr_inputs = glue->nr_outputs;
    }
    else if (ranges->sizeof_array != sizeof(unsigned_cell) * 2) {
      device_error(me, "invalid interrupt-ranges property (incorrect size)");
    }
    else {
      const unsigned_cell *int_range = ranges->array;
      glue->int_number = BE2H_cell(int_range[0]);
      glue->nr_inputs = BE2H_cell(int_range[1]);
    }
    glue->sizeof_input = glue->nr_inputs * sizeof(unsigned);
    glue->input = zalloc(glue->sizeof_input);
  }

  /* determine our type */
  if (glue->type == glue_undefined) {
    const char *name = device_name(me);
    if (strcmp(name, "glue") == 0)
      glue->type = glue_io;
    else if (strcmp(name, "glue-and") == 0)
      glue->type = glue_and;
    else
      device_error(me, "unimplemented glue type");
  }

  DTRACE(glue, ("int-number %d, nr_inputs %d, nr_outputs %d\n",
		glue->int_number, glue->nr_inputs, glue->nr_outputs));
}

static unsigned
hw_glue_io_read_buffer_callback(device *me,
				void *dest,
				int space,
				unsigned_word addr,
				unsigned nr_bytes,
				cpu *processor,
				unsigned_word cia)
{
  hw_glue_device *glue = (hw_glue_device*)device_data(me);
  int reg = ((addr - glue->address) / sizeof(unsigned_word)) % glue->nr_outputs;
  if (nr_bytes != sizeof(unsigned_word)
      || (addr % sizeof(unsigned_word)) != 0)
     device_error(me, "missaligned read access (%d:0x%lx:%d) not supported",
		  space, (unsigned long)addr, nr_bytes);
  *(unsigned_word*)dest = H2BE_4(glue->output[reg]);
  DTRACE(glue, ("read - interrupt %d (0x%lx), level %d\n",
		reg, (unsigned long) addr, glue->output[reg]));
  return nr_bytes;
}


static unsigned
hw_glue_io_write_buffer_callback(device *me,
				 const void *source,
				 int space,
				 unsigned_word addr,
				 unsigned nr_bytes,
				 cpu *processor,
				 unsigned_word cia)
{
  hw_glue_device *glue = (hw_glue_device*)device_data(me);
  int reg = ((addr - glue->address) / sizeof(unsigned_word)) % max_nr_interrupts;
  if (nr_bytes != sizeof(unsigned_word)
      || (addr % sizeof(unsigned_word)) != 0)
    device_error(me, "missaligned write access (%d:0x%lx:%d) not supported",
		 space, (unsigned long)addr, nr_bytes);
  glue->output[reg] = H2BE_4(*(unsigned_word*)source);
  DTRACE(glue, ("write - interrupt %d (0x%lx), level %d\n",
		reg, (unsigned long) addr, glue->output[reg]));
  device_interrupt_event(me, reg, glue->output[reg], processor, cia);
  return nr_bytes;
}

static void
hw_glue_interrupt_event(device *me,
			int my_port,
			device *source,
			int source_port,
			int level,
			cpu *processor,
			unsigned_word cia)
{
  hw_glue_device *glue = (hw_glue_device*)device_data(me);
  int i;
  if (my_port < glue->int_number
      || my_port >= glue->int_number + glue->nr_inputs)
    device_error(me, "interrupt %d outside of valid range", my_port);
  glue->input[my_port - glue->int_number] = level;
  switch (glue->type) {
  case glue_io:
    {
      int port = my_port % glue->nr_outputs;
      glue->output[port] = level;
      DTRACE(glue, ("input - interrupt %d (0x%lx), level %d\n",
		    my_port,
		    (unsigned long)glue->address + port * sizeof(unsigned_word),
		    level));
      break;
    }
  case glue_and:
    glue->output[0] = glue->input[0];
    for (i = 1; i < glue->nr_inputs; i++)
      glue->output[0] &= glue->input[i];
    DTRACE(glue, ("and - interrupt %d, level %d arrived - output %d\n",
		  my_port, level, glue->output[0]));
    device_interrupt_event(me, 0, glue->output[0], processor, cia);
    break;
  default:
    device_error(me, "operator not implemented");
    break;
  }
}


static const device_interrupt_port_descriptor hw_glue_interrupt_ports[] = {
  { "int", 0, max_nr_interrupts },
  { NULL }
};


static device_callbacks const hw_glue_callbacks = {
  { hw_glue_init_address, NULL },
  { NULL, }, /* address */
  { hw_glue_io_read_buffer_callback,
      hw_glue_io_write_buffer_callback, },
  { NULL, }, /* DMA */
  { hw_glue_interrupt_event, NULL, hw_glue_interrupt_ports }, /* interrupt */
  { NULL, }, /* unit */
  NULL, /* instance */
};


static void *
hw_glue_create(const char *name,
	      const device_unit *unit_address,
	      const char *args)
{
  /* create the descriptor */
  hw_glue_device *glue = ZALLOC(hw_glue_device);
  return glue;
}


const device_descriptor hw_glue_device_descriptor[] = {
  { "glue", hw_glue_create, &hw_glue_callbacks },
  { "glue-and", hw_glue_create, &hw_glue_callbacks },
  { "glue-nand", hw_glue_create, &hw_glue_callbacks },
  { "glue-or", hw_glue_create, &hw_glue_callbacks },
  { "glue-xor", hw_glue_create, &hw_glue_callbacks },
  { "glue-nor", hw_glue_create, &hw_glue_callbacks },
  { "glue-not", hw_glue_create, &hw_glue_callbacks },
  { NULL },
};

#endif /* _HW_GLUE_C_ */
