/*  Lattice Mico32 CPU model.
    Contributed by Jon Beniston <jon@beniston.com>

   Copyright (C) 2009, 2010 Free Software Foundation, Inc.

   This file is part of GDB.

   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 "hw-main.h"
#include "sim-main.h"


struct lm32cpu
{
  struct hw_event *event;
};

/* input port ID's.  */

enum
{
  INT0_PORT,
  INT1_PORT,
  INT2_PORT,
  INT3_PORT,
  INT4_PORT,
  INT5_PORT,
  INT6_PORT,
  INT7_PORT,
  INT8_PORT,
  INT9_PORT,
  INT10_PORT,
  INT11_PORT,
  INT12_PORT,
  INT13_PORT,
  INT14_PORT,
  INT15_PORT,
  INT16_PORT,
  INT17_PORT,
  INT18_PORT,
  INT19_PORT,
  INT20_PORT,
  INT21_PORT,
  INT22_PORT,
  INT23_PORT,
  INT24_PORT,
  INT25_PORT,
  INT26_PORT,
  INT27_PORT,
  INT28_PORT,
  INT29_PORT,
  INT30_PORT,
  INT31_PORT,
};

static const struct hw_port_descriptor lm32cpu_ports[] = {
  /* interrupt inputs.  */
  {"int0", INT0_PORT, 0, input_port,},
  {"int1", INT1_PORT, 0, input_port,},
  {"int2", INT2_PORT, 0, input_port,},
  {"int3", INT3_PORT, 0, input_port,},
  {"int4", INT4_PORT, 0, input_port,},
  {"int5", INT5_PORT, 0, input_port,},
  {"int6", INT6_PORT, 0, input_port,},
  {"int7", INT7_PORT, 0, input_port,},
  {"int8", INT8_PORT, 0, input_port,},
  {"int9", INT9_PORT, 0, input_port,},
  {"int10", INT10_PORT, 0, input_port,},
  {"int11", INT11_PORT, 0, input_port,},
  {"int12", INT12_PORT, 0, input_port,},
  {"int13", INT13_PORT, 0, input_port,},
  {"int14", INT14_PORT, 0, input_port,},
  {"int15", INT15_PORT, 0, input_port,},
  {"int16", INT16_PORT, 0, input_port,},
  {"int17", INT17_PORT, 0, input_port,},
  {"int18", INT18_PORT, 0, input_port,},
  {"int19", INT19_PORT, 0, input_port,},
  {"int20", INT20_PORT, 0, input_port,},
  {"int21", INT21_PORT, 0, input_port,},
  {"int22", INT22_PORT, 0, input_port,},
  {"int23", INT23_PORT, 0, input_port,},
  {"int24", INT24_PORT, 0, input_port,},
  {"int25", INT25_PORT, 0, input_port,},
  {"int26", INT26_PORT, 0, input_port,},
  {"int27", INT27_PORT, 0, input_port,},
  {"int28", INT28_PORT, 0, input_port,},
  {"int29", INT29_PORT, 0, input_port,},
  {"int30", INT30_PORT, 0, input_port,},
  {"int31", INT31_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 lm32cpu_port_event;


static void
lm32cpu_finish (struct hw *me)
{
  struct lm32cpu *controller;

  controller = HW_ZALLOC (me, struct lm32cpu);
  set_hw_data (me, controller);
  set_hw_ports (me, lm32cpu_ports);
  set_hw_port_event (me, lm32cpu_port_event);

  /* Initialize the pending interrupt flags.  */
  controller->event = NULL;
}


/* An event arrives on an interrupt port.  */
static unsigned int s_ui_ExtIntrs = 0;


static void
deliver_lm32cpu_interrupt (struct hw *me, void *data)
{
  static unsigned int ip, im, im_and_ip_result;
  struct lm32cpu *controller = hw_data (me);
  SIM_DESC sd = hw_system (me);
  sim_cpu *cpu = STATE_CPU (sd, 0);	/* NB: fix CPU 0.  */
  address_word cia = CIA_GET (cpu);
  int interrupt = (int) data;


  HW_TRACE ((me, "interrupt-check event"));


  /*
   * Determine if an external interrupt is active 
   * and needs to cause an exception.
   */
  im = lm32bf_h_csr_get (cpu, LM32_CSR_IM);
  ip = lm32bf_h_csr_get (cpu, LM32_CSR_IP);
  im_and_ip_result = im & ip;


  if ((lm32bf_h_csr_get (cpu, LM32_CSR_IE) & 1) && (im_and_ip_result != 0))
    {
      /* Save PC in exception address register.  */
      lm32bf_h_gr_set (cpu, 30, lm32bf_h_pc_get (cpu));
      /* Restart at interrupt offset in handler exception table.  */
      lm32bf_h_pc_set (cpu,
		       lm32bf_h_csr_get (cpu,
					 LM32_CSR_EBA) +
		       LM32_EID_INTERRUPT * 32);
      /* Save interrupt enable and then clear.  */
      lm32bf_h_csr_set (cpu, LM32_CSR_IE, 0x2);
    }

  /* reschedule soon.  */
  if (controller->event != NULL)
    hw_event_queue_deschedule (me, controller->event);
  controller->event = NULL;


  /* if there are external interrupts, schedule an interrupt-check again.
   * NOTE: THIS MAKES IT VERY INEFFICIENT. INSTEAD, TRIGGER THIS
   * CHECk_EVENT WHEN THE USER ENABLES IE OR USER MODIFIES IM REGISTERS.
   */
  if (s_ui_ExtIntrs != 0)
    controller->event =
      hw_event_queue_schedule (me, 1, deliver_lm32cpu_interrupt, data);
}



/* Handle an event on one of the CPU's ports.  */
static void
lm32cpu_port_event (struct hw *me,
		    int my_port,
		    struct hw *source, int source_port, int level)
{
  struct lm32cpu *controller = hw_data (me);
  SIM_DESC sd = hw_system (me);
  sim_cpu *cpu = STATE_CPU (sd, 0);	/* NB: fix CPU 0.  */
  address_word cia = CIA_GET (cpu);


  HW_TRACE ((me, "interrupt event on port %d, level %d", my_port, level));



  /* 
   * Activate IP if the interrupt's activated; don't do anything if
   * the interrupt's deactivated.
   */
  if (level == 1)
    {
      /*
       * save state of external interrupt.
       */
      s_ui_ExtIntrs |= (1 << my_port);

      /* interrupt-activated so set IP.  */
      lm32bf_h_csr_set (cpu, LM32_CSR_IP,
			lm32bf_h_csr_get (cpu, LM32_CSR_IP) | (1 << my_port));

      /* 
       * Since interrupt is activated, queue an immediate event
       * to check if this interrupt is serviceable.
       */
      if (controller->event != NULL)
	hw_event_queue_deschedule (me, controller->event);


      /* 
       * Queue an immediate event to check if this interrupt must be serviced;
       * this will happen after the current instruction is complete.
       */
      controller->event = hw_event_queue_schedule (me,
						   0,
						   deliver_lm32cpu_interrupt,
						   0);
    }
  else
    {
      /*
       * save state of external interrupt.
       */
      s_ui_ExtIntrs &= ~(1 << my_port);
    }
}


const struct hw_descriptor dv_lm32cpu_descriptor[] = {
  {"lm32cpu", lm32cpu_finish,},
  {NULL},
};
