/*  This file is part of the program GDB, the GNU debugger.
    
    Copyright (C) 1998-2021 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/>.
    
    */

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

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

/* DEVICE

   
   tx3904cpu - tx3904 cpu virtual device

   
   DESCRIPTION

   
   Implements the external tx3904 functionality.  This includes the
   delivery of of interrupts generated from other devices and the
   handling of device specific registers.


   PROPERTIES
   
   none


   PORTS


   reset (input)

   Currently ignored.


   nmi (input)

   Deliver a non-maskable interrupt to the processor.


   level (input)

   Deliver a maskable interrupt of given level, corresponding to
   IP[5:0], to processor.



   BUGS


   When delivering an interrupt, this code assumes that there is only
   one processor (number 0).

   This code does not attempt to be efficient at handling pending
   interrupts.  It simply schedules the interrupt delivery handler
   every instruction cycle until all pending interrupts go away.  An
   alternative implementation might modify instructions that change
   the PSW and have them check to see if the change makes an interrupt
   delivery possible.

   */



struct tx3904cpu {
  /* Pending interrupts for delivery by event handler */
  int pending_reset, pending_nmi, pending_level;
  struct hw_event* event;
};



/* input port ID's */ 

enum {
  RESET_PORT,
  NMI_PORT,
  LEVEL_PORT,
};


static const struct hw_port_descriptor tx3904cpu_ports[] = {

  /* interrupt inputs */
  { "reset", RESET_PORT, 0, input_port, },
  { "nmi", NMI_PORT, 0, input_port, },
  { "level", LEVEL_PORT, 0, input_port, },

  { NULL, },
};


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

static hw_port_event_method tx3904cpu_port_event;



static void
tx3904cpu_finish (struct hw *me)
{
  struct tx3904cpu *controller;

  controller = HW_ZALLOC (me, struct tx3904cpu);
  set_hw_data (me, controller);
  set_hw_ports (me, tx3904cpu_ports);
  set_hw_port_event (me, tx3904cpu_port_event);

  /* Initialize the pending interrupt flags */
  controller->pending_level = 0;
  controller->pending_reset = 0;
  controller->pending_nmi = 0;
  controller->event = NULL;
}



/* An event arrives on an interrupt port */

static void
deliver_tx3904cpu_interrupt (struct hw *me,
			    void *data)
{
  struct tx3904cpu *controller = hw_data (me);
  SIM_DESC sd = hw_system (me);
  sim_cpu *cpu = STATE_CPU (sd, 0); /* NB: fix CPU 0. */
  address_word cia = CPU_PC_GET (cpu);

#define CPU cpu
#define SD sd

  if (controller->pending_reset)
    {
      controller->pending_reset = 0;
      HW_TRACE ((me, "reset pc=0x%08lx", (long) CPU_PC_GET (cpu)));
      SignalExceptionNMIReset();
    }
  else if (controller->pending_nmi)
    {
      controller->pending_nmi = 0;
      HW_TRACE ((me, "nmi pc=0x%08lx", (long) CPU_PC_GET (cpu)));
      SignalExceptionNMIReset();
    }
  else if (controller->pending_level)
    {
      HW_TRACE ((me, "interrupt level=%d pc=0x%08lx sr=0x%08lx",
		 controller->pending_level,
		 (long) CPU_PC_GET (cpu), (long) SR));

      /* Clear CAUSE register.  It may stay this way if the interrupt
	 was cleared with a negative pending_level. */
      CAUSE &= ~ (cause_IP_mask << cause_IP_shift);

      if(controller->pending_level > 0) /* interrupt set */
	{
	  /* set hardware-interrupt subfields of CAUSE register */
	  CAUSE |= (controller->pending_level & cause_IP_mask) << cause_IP_shift;

	  /* check for enabled / unmasked interrupts */
	  if((SR & status_IEc) &&
	     (controller->pending_level & ((SR >> status_IM_shift) & status_IM_mask)))
	    {
	      controller->pending_level = 0;
	      SignalExceptionInterrupt(0 /* dummy value */);
	    }
	  else
	    {
	      /* reschedule soon */
	      if(controller->event != NULL)
		hw_event_queue_deschedule(me, controller->event);
	      controller->event =
		hw_event_queue_schedule (me, 1, deliver_tx3904cpu_interrupt, NULL);
	    }
	} /* interrupt set */
    }
#undef CPU
#undef SD
}


static void
tx3904cpu_port_event (struct hw *me,
		     int my_port,
		     struct hw *source,
		     int source_port,
		     int level)
{
  struct tx3904cpu *controller = hw_data (me);

  switch (my_port)
    {      
    case RESET_PORT:
      controller->pending_reset = 1;
      HW_TRACE ((me, "port-in reset"));
      break;
      
    case NMI_PORT:
      controller->pending_nmi = 1;
      HW_TRACE ((me, "port-in nmi"));
      break;
      
    case LEVEL_PORT:
      /* level == 0 means that the interrupt was cleared */
      if(level == 0)
	controller->pending_level = -1; /* signal end of interrupt */
      else
	controller->pending_level = level;
      HW_TRACE ((me, "port-in level=%d", level));
      break;
      
    default:
      hw_abort (me, "bad switch");
      break;
    }

  /* Schedule an event to be delivered immediately after current
     instruction. */
  if(controller->event != NULL)
    hw_event_queue_deschedule(me, controller->event);
  controller->event =
    hw_event_queue_schedule (me, 0, deliver_tx3904cpu_interrupt, NULL);
}


const struct hw_descriptor dv_tx3904cpu_descriptor[] = {
  { "tx3904cpu", tx3904cpu_finish, },
  { NULL },
};
