/*  This file is part of the program psim.

    Copyright 1994, 1995, 1996, 1997, 2003 Andrew Cagney

    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 _INTERRUPTS_C_
#define _INTERRUPTS_C_

#include <signal.h>

#include "cpu.h"
#include "idecode.h"
#include "os_emul.h"


/* Operating environment support code

   Unlike the VEA, the OEA must fully model the effect an interrupt
   has on the processors state.

   Each function below return updated values for registers effected by
   interrupts */


STATIC_INLINE_INTERRUPTS\
(msreg)
interrupt_msr(msreg old_msr,
	      msreg msr_clear,
	      msreg msr_set)
{
  msreg msr_set_to_0 = (msr_branch_trace_enable
			| msr_data_relocate
			| msr_external_interrupt_enable
			| msr_floating_point_exception_mode_0
			| msr_floating_point_exception_mode_1
			| msr_floating_point_available
			| msr_instruction_relocate
			| msr_power_management_enable
			| msr_problem_state
			| msr_recoverable_interrupt
			| msr_single_step_trace_enable);
  /* remember, in 32bit mode msr_64bit_mode is zero */
  msreg new_msr = ((((old_msr & ~msr_set_to_0)
		     | msr_64bit_mode)
		    & ~msr_clear)
		   | msr_set);
  return new_msr;
}


STATIC_INLINE_INTERRUPTS\
(msreg)
interrupt_srr1(msreg old_msr,
	       msreg srr1_clear,
	       msreg srr1_set)
{
  spreg srr1_mask = (MASK(0,32)
		     | MASK(37, 41)
		     | MASK(48, 63));
  spreg srr1 = (old_msr & srr1_mask & ~srr1_clear) | srr1_set;
  return srr1;
}


STATIC_INLINE_INTERRUPTS\
(unsigned_word)
interrupt_base_ea(msreg msr)
{
  if (msr & msr_interrupt_prefix)
    return MASK(0, 43);
  else
    return 0;
}


/* finish off an interrupt for the OEA model, updating all registers
   and forcing a restart of the processor */

STATIC_INLINE_INTERRUPTS\
(unsigned_word)
perform_oea_interrupt(cpu *processor,
		      unsigned_word cia,
		      unsigned_word vector_offset,
		      msreg msr_clear,
		      msreg msr_set,
		      msreg srr1_clear,
		      msreg srr1_set)
{
  msreg old_msr = MSR;
  msreg new_msr = interrupt_msr(old_msr, msr_clear, msr_set);
  unsigned_word nia;
  if (!(old_msr & msr_recoverable_interrupt)) {
    cpu_error(processor, cia,
	      "double interrupt - MSR[RI] bit clear when attempting to deliver interrupt, cia=0x%lx, msr=0x%lx; srr0=0x%lx(cia), srr1=0x%lx(msr); trap-vector=0x%lx, trap-msr=0x%lx",
	      (unsigned long)cia,
	      (unsigned long)old_msr,
	      (unsigned long)SRR0,
	      (unsigned long)SRR1,
	      (unsigned long)vector_offset,
	      (unsigned long)new_msr);
  }
  SRR0 = (spreg)(cia);
  SRR1 = interrupt_srr1(old_msr, srr1_clear, srr1_set);
  MSR = new_msr;
  nia = interrupt_base_ea(new_msr) + vector_offset;
  cpu_synchronize_context(processor, cia);
  return nia;
}


INLINE_INTERRUPTS\
(void)
machine_check_interrupt(cpu *processor,
			unsigned_word cia)
{
  switch (CURRENT_ENVIRONMENT) {

  case USER_ENVIRONMENT:
  case VIRTUAL_ENVIRONMENT:
    cpu_error(processor, cia, "machine-check interrupt");

  case OPERATING_ENVIRONMENT:
    TRACE(trace_interrupts, ("machine-check interrupt - cia=0x%lx\n",
			     (unsigned long)cia));
    cia = perform_oea_interrupt(processor, cia, 0x00200, 0, 0, 0, 0);
    cpu_restart(processor, cia);

  default:
    error("internal error - machine_check_interrupt - bad switch");

  }
}


INLINE_INTERRUPTS\
(void)
data_storage_interrupt(cpu *processor,
		       unsigned_word cia,
		       unsigned_word ea,
		       storage_interrupt_reasons reason,
		       int is_store)
{
  switch (CURRENT_ENVIRONMENT) {

  case USER_ENVIRONMENT:
  case VIRTUAL_ENVIRONMENT:
    error("internal error - data_storage_interrupt - should not be called in VEA mode");
    break;

  case OPERATING_ENVIRONMENT:
    {
      spreg direction = (is_store ? dsisr_store_operation : 0);
      switch (reason) {
      case direct_store_storage_interrupt:
	DSISR = dsisr_direct_store_error_exception | direction;
	break;
      case hash_table_miss_storage_interrupt:
	DSISR = dsisr_hash_table_or_dbat_miss | direction;
	break;
      case protection_violation_storage_interrupt:
	DSISR = dsisr_protection_violation | direction;
	break;
      case earwax_violation_storage_interrupt:
	DSISR = dsisr_earwax_violation | direction;
	break;
      case segment_table_miss_storage_interrupt:
	DSISR = dsisr_segment_table_miss | direction;
	break;
      case earwax_disabled_storage_interrupt:
	DSISR = dsisr_earwax_disabled | direction;
	break;
      default:
	error("internal error - data_storage_interrupt - reason %d not implemented", reason);
	break;
      }
      DAR = (spreg)ea;
      TRACE(trace_interrupts, ("data storage interrupt - cia=0x%lx DAR=0x%lx DSISR=0x%lx\n",
			       (unsigned long)cia,
			       (unsigned long)DAR,
			       (unsigned long)DSISR));
      cia = perform_oea_interrupt(processor, cia, 0x00300, 0, 0, 0, 0);
      cpu_restart(processor, cia);
    }

  default:
    error("internal error - data_storage_interrupt - bad switch");

  }
}


INLINE_INTERRUPTS\
(void)
instruction_storage_interrupt(cpu *processor,
			      unsigned_word cia,
			      storage_interrupt_reasons reason)
{
  switch (CURRENT_ENVIRONMENT) {

  case USER_ENVIRONMENT:
  case VIRTUAL_ENVIRONMENT:
    error("internal error - instruction_storage_interrupt - should not be called in VEA mode");

  case OPERATING_ENVIRONMENT:
    {
      msreg srr1_set;
      switch(reason) {
      case hash_table_miss_storage_interrupt:
	srr1_set = srr1_hash_table_or_ibat_miss;
	break;
      case direct_store_storage_interrupt:
	srr1_set = srr1_direct_store_error_exception;
	break;
      case protection_violation_storage_interrupt:
	srr1_set = srr1_protection_violation;
	break;
      case segment_table_miss_storage_interrupt:
	srr1_set = srr1_segment_table_miss;
	break;
      default:
	srr1_set = 0;
	error("internal error - instruction_storage_interrupt - reason %d not implemented", reason);
	break;
      }
      TRACE(trace_interrupts, ("instruction storage interrupt - cia=0x%lx SRR1|=0x%lx\n",
			       (unsigned long)cia,
			       (unsigned long)srr1_set));
      cia = perform_oea_interrupt(processor, cia, 0x00400, 0, 0, 0, srr1_set);
      cpu_restart(processor, cia);
    }

  default:
    error("internal error - instruction_storage_interrupt - bad switch");

  }
}



INLINE_INTERRUPTS\
(void)
alignment_interrupt(cpu *processor,
		    unsigned_word cia,
		    unsigned_word ra)
{
  switch (CURRENT_ENVIRONMENT) {

  case USER_ENVIRONMENT:
  case VIRTUAL_ENVIRONMENT:
    cpu_error(processor, cia, "alignment interrupt - ra=0x%lx", (unsigned long)ra);
    
  case OPERATING_ENVIRONMENT:
    DAR = (spreg)ra;
    DSISR = 0; /* FIXME */
    TRACE(trace_interrupts, ("alignment interrupt - cia=0x%lx DAR=0x%lx DSISR=0x%lx\n",
			     (unsigned long)cia,
			     (unsigned long)DAR,
			     (unsigned long)DSISR));
    cia = perform_oea_interrupt(processor, cia, 0x00600, 0, 0, 0, 0);
    cpu_restart(processor, cia);

  default:
    error("internal error - alignment_interrupt - bad switch");
    
  }
}




INLINE_INTERRUPTS\
(void)
program_interrupt(cpu *processor,
		  unsigned_word cia,
		  program_interrupt_reasons reason)
{
  switch (CURRENT_ENVIRONMENT) {

  case USER_ENVIRONMENT:
  case VIRTUAL_ENVIRONMENT:
    switch (reason) {
    case floating_point_enabled_program_interrupt:
      cpu_error(processor, cia, "program interrupt - %s",
		"floating point enabled");
      break;
    case illegal_instruction_program_interrupt:
      cpu_error(processor, cia, "program interrupt - %s",
		"illegal instruction");
      break;
    case privileged_instruction_program_interrupt:
      cpu_error(processor, cia, "program interrupt - %s",
		"privileged instruction");
      break;
    case trap_program_interrupt:
      cpu_error(processor, cia, "program interrupt - %s",
		"trap");
      break;
    case optional_instruction_program_interrupt:
      cpu_error(processor, cia, "program interrupt - %s",
		"illegal instruction (optional instruction not supported)");
      break;
    case mpc860c0_instruction_program_interrupt:
      cpu_error(processor, cia, "program interrupt - %s",
        	"problematic branch detected, see MPC860 C0 errata");
      break;
    default:
      error("internal error - program_interrupt - reason %d not implemented", reason);
    }

  case OPERATING_ENVIRONMENT:
    {
      msreg srr1_set;
      switch (reason) {
      case floating_point_enabled_program_interrupt:
	srr1_set = srr1_floating_point_enabled;
	break;
      case optional_instruction_program_interrupt:
      case illegal_instruction_program_interrupt:
	srr1_set = srr1_illegal_instruction;
	break;
      case privileged_instruction_program_interrupt:
	srr1_set = srr1_priviliged_instruction;
	break;
      case trap_program_interrupt:
	srr1_set = srr1_trap;
	break;
      case mpc860c0_instruction_program_interrupt:
        srr1_set = 0;
        cpu_error(processor, cia, "program interrupt - %s",
              "problematic branch detected, see MPC860 C0 errata");
        break;
      default:
	srr1_set = 0;
	error("internal error - program_interrupt - reason %d not implemented", reason);
	break;
      }
      TRACE(trace_interrupts, ("program interrupt - cia=0x%lx SRR1|=0x%lx\n",
			       (unsigned long)cia,
			       (unsigned long)srr1_set));
      cia = perform_oea_interrupt(processor, cia, 0x00700, 0, 0, 0, srr1_set);
      cpu_restart(processor, cia);
    }

  default:
    error("internal error - program_interrupt - bad switch");

  }
}


INLINE_INTERRUPTS\
(void)
floating_point_unavailable_interrupt(cpu *processor,
				     unsigned_word cia)
{
  switch (CURRENT_ENVIRONMENT) {
    
  case USER_ENVIRONMENT:
  case VIRTUAL_ENVIRONMENT:
    cpu_error(processor, cia, "floating-point unavailable interrupt");

  case OPERATING_ENVIRONMENT:
    TRACE(trace_interrupts, ("floating-point unavailable interrupt - cia=0x%lx\n",
			     (unsigned long)cia));
    cia = perform_oea_interrupt(processor, cia, 0x00800, 0, 0, 0, 0);
    cpu_restart(processor, cia);

  default:
    error("internal error - floating_point_unavailable_interrupt - bad switch");

  }
}


INLINE_INTERRUPTS\
(void)
system_call_interrupt(cpu *processor,
		      unsigned_word cia)
{
  TRACE(trace_interrupts, ("system-call interrupt - cia=0x%lx\n", (unsigned long)cia));

  switch (CURRENT_ENVIRONMENT) {

  case USER_ENVIRONMENT:
  case VIRTUAL_ENVIRONMENT:
    os_emul_system_call(processor, cia);
    cpu_restart(processor, cia+4);

  case OPERATING_ENVIRONMENT:
    cia = perform_oea_interrupt(processor, cia+4, 0x00c00, 0, 0, 0, 0);
    cpu_restart(processor, cia);

  default:
    error("internal error - system_call_interrupt - bad switch");

  }
}

INLINE_INTERRUPTS\
(void)
floating_point_assist_interrupt(cpu *processor,
				unsigned_word cia)
{
  switch (CURRENT_ENVIRONMENT) {

  case USER_ENVIRONMENT:
  case VIRTUAL_ENVIRONMENT:
    cpu_error(processor, cia, "floating-point assist interrupt");

  case OPERATING_ENVIRONMENT:
    TRACE(trace_interrupts, ("floating-point assist interrupt - cia=0x%lx\n", (unsigned long)cia));
    cia = perform_oea_interrupt(processor, cia, 0x00e00, 0, 0, 0, 0);
    cpu_restart(processor, cia);

  default:
    error("internal error - floating_point_assist_interrupt - bad switch");

  }
}



/* handle an externally generated event or an interrupt that has just
   been enabled through changes to the MSR. */

STATIC_INLINE_INTERRUPTS\
(void)
deliver_hardware_interrupt(void *data)
{
  cpu *processor = (cpu*)data;
  interrupts *ints = cpu_interrupts(processor);
  ints->delivery_scheduled = NULL;
  if ((cpu_registers(processor)->msr & (msr_floating_point_exception_mode_0
					| msr_floating_point_exception_mode_1))
      && cpu_registers(processor)->fpscr & fpscr_fex) {
    msreg srr1_set = srr1_floating_point_enabled | srr1_subsequent_instruction;
    unsigned_word cia = cpu_get_program_counter(processor);
    unsigned_word nia = perform_oea_interrupt(processor,
					      cia, 0x00700, 0, 0, 0, srr1_set);
    cpu_set_program_counter(processor, nia);
  }
  else if (cpu_registers(processor)->msr & msr_external_interrupt_enable) {
    /* external interrupts have a high priority and remain pending */
    if (ints->pending_interrupts & external_interrupt_pending) {
      unsigned_word cia = cpu_get_program_counter(processor);
      unsigned_word nia = perform_oea_interrupt(processor,
						cia, 0x00500, 0, 0, 0, 0);
      TRACE(trace_interrupts, ("external interrupt - cia=0x%lx\n", (unsigned long)cia));
      cpu_set_program_counter(processor, nia);
    }
    /* decrementer interrupts have a lower priority and are once only */
    else if (ints->pending_interrupts & decrementer_interrupt_pending) {
      unsigned_word cia = cpu_get_program_counter(processor);
      unsigned_word nia = perform_oea_interrupt(processor,
						cia, 0x00900, 0, 0, 0, 0);
      TRACE(trace_interrupts, ("decrementer interrupt - cia 0x%lx, time %ld\n",
			       (unsigned long)cia,
			       (unsigned long)event_queue_time(psim_event_queue(cpu_system(processor)))
			       ));
      cpu_set_program_counter(processor, nia);
      ints->pending_interrupts &= ~decrementer_interrupt_pending;
    }
  }
}

STATIC_INLINE_INTERRUPTS\
(void)
schedule_hardware_interrupt_delivery(cpu *processor) 
{
  interrupts *ints = cpu_interrupts(processor);
  if (ints->delivery_scheduled == NULL) {
    ints->delivery_scheduled =
      event_queue_schedule(psim_event_queue(cpu_system(processor)),
			   0, deliver_hardware_interrupt, processor);
  }
}


INLINE_INTERRUPTS\
(void)
check_masked_interrupts(cpu *processor)
{
  if (((cpu_registers(processor)->msr & (msr_floating_point_exception_mode_0
					 | msr_floating_point_exception_mode_1))
       && cpu_registers(processor)->fpscr & fpscr_fex)
      || ((cpu_registers(processor)->msr & msr_external_interrupt_enable)
	  && (cpu_interrupts(processor)->pending_interrupts)))
    schedule_hardware_interrupt_delivery(processor);
}

INLINE_INTERRUPTS\
(void)
decrementer_interrupt(cpu *processor)
{
  interrupts *ints = cpu_interrupts(processor);
  ints->pending_interrupts |= decrementer_interrupt_pending;
  if (cpu_registers(processor)->msr & msr_external_interrupt_enable) {
    schedule_hardware_interrupt_delivery(processor);
  }
}

INLINE_INTERRUPTS\
(void)
external_interrupt(cpu *processor,
		   int is_asserted)
{
  interrupts *ints = cpu_interrupts(processor);
  if (is_asserted) {
    if (!(ints->pending_interrupts & external_interrupt_pending)) {
      ints->pending_interrupts |= external_interrupt_pending;
      if (cpu_registers(processor)->msr & msr_external_interrupt_enable)
	schedule_hardware_interrupt_delivery(processor);
    }
    else {
      /* check that we haven't missed out on a chance to deliver an
         interrupt */
      ASSERT(!(cpu_registers(processor)->msr & msr_external_interrupt_enable));
    }
  }
  else {
    ints->pending_interrupts &= ~external_interrupt_pending;
  }
}

#endif /* _INTERRUPTS_C_ */
