/* interp.c -- Simulator for Motorola 68HC11/68HC12
   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2007, 2008, 2009, 2010,
   2011 Free Software Foundation, Inc.
   Written by Stephane Carrez (stcarrez@nerim.fr)

This file is part of GDB, the GNU debugger.

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 "sim-main.h"
#include "sim-assert.h"
#include "sim-hw.h"
#include "sim-options.h"
#include "hw-tree.h"
#include "hw-device.h"
#include "hw-ports.h"
#include "elf32-m68hc1x.h"

#ifndef MONITOR_BASE
# define MONITOR_BASE (0x0C000)
# define MONITOR_SIZE (0x04000)
#endif

static void sim_get_info (SIM_DESC sd, char *cmd);


char *interrupt_names[] = {
  "reset",
  "nmi",
  "int",
  NULL
};

#ifndef INLINE
#if defined(__GNUC__) && defined(__OPTIMIZE__)
#define INLINE __inline__
#else
#define INLINE
#endif
#endif

struct sim_info_list
{
  const char *name;
  const char *device;
};

struct sim_info_list dev_list_68hc11[] = {
  {"cpu", "/m68hc11"},
  {"timer", "/m68hc11/m68hc11tim"},
  {"sio", "/m68hc11/m68hc11sio"},
  {"spi", "/m68hc11/m68hc11spi"},
  {"eeprom", "/m68hc11/m68hc11eepr"},
  {0, 0}
};

struct sim_info_list dev_list_68hc12[] = {
  {"cpu", "/m68hc12"},
  {"timer", "/m68hc12/m68hc12tim"},
  {"sio", "/m68hc12/m68hc12sio"},
  {"spi", "/m68hc12/m68hc12spi"},
  {"eeprom", "/m68hc12/m68hc12eepr"},
  {0, 0}
};

/* Cover function of sim_state_free to free the cpu buffers as well.  */

static void
free_state (SIM_DESC sd)
{
  if (STATE_MODULES (sd) != NULL)
    sim_module_uninstall (sd);

  sim_state_free (sd);
}

/* Give some information about the simulator.  */
static void
sim_get_info (SIM_DESC sd, char *cmd)
{
  sim_cpu *cpu;

  cpu = STATE_CPU (sd, 0);
  if (cmd != 0 && (cmd[0] == ' ' || cmd[0] == '-'))
    {
      int i;
      struct hw *hw_dev;
      struct sim_info_list *dev_list;
      const struct bfd_arch_info *arch;

      arch = STATE_ARCHITECTURE (sd);
      cmd++;

      if (arch->arch == bfd_arch_m68hc11)
        dev_list = dev_list_68hc11;
      else
        dev_list = dev_list_68hc12;

      for (i = 0; dev_list[i].name; i++)
	if (strcmp (cmd, dev_list[i].name) == 0)
	  break;

      if (dev_list[i].name == 0)
	{
	  sim_io_eprintf (sd, "Device '%s' not found.\n", cmd);
	  sim_io_eprintf (sd, "Valid devices: cpu timer sio eeprom\n");
	  return;
	}
      hw_dev = sim_hw_parse (sd, dev_list[i].device);
      if (hw_dev == 0)
	{
	  sim_io_eprintf (sd, "Device '%s' not found\n", dev_list[i].device);
	  return;
	}
      hw_ioctl (hw_dev, 23, 0);
      return;
    }

  cpu_info (sd, cpu);
  interrupts_info (sd, &cpu->cpu_interrupts);
}


void
sim_board_reset (SIM_DESC sd)
{
  struct hw *hw_cpu;
  sim_cpu *cpu;
  const struct bfd_arch_info *arch;
  const char *cpu_type;

  cpu = STATE_CPU (sd, 0);
  arch = STATE_ARCHITECTURE (sd);

  /*  hw_cpu = sim_hw_parse (sd, "/"); */
  if (arch->arch == bfd_arch_m68hc11)
    {
      cpu->cpu_type = CPU_M6811;
      cpu_type = "/m68hc11";
    }
  else
    {
      cpu->cpu_type = CPU_M6812;
      cpu_type = "/m68hc12";
    }
  
  hw_cpu = sim_hw_parse (sd, cpu_type);
  if (hw_cpu == 0)
    {
      sim_io_eprintf (sd, "%s cpu not found in device tree.", cpu_type);
      return;
    }

  cpu_reset (cpu);
  hw_port_event (hw_cpu, 3, 0);
  cpu_restart (cpu);
}

static int
sim_hw_configure (SIM_DESC sd)
{
  const struct bfd_arch_info *arch;
  struct hw *device_tree;
  sim_cpu *cpu;
  
  arch = STATE_ARCHITECTURE (sd);
  if (arch == 0)
    return 0;

  cpu = STATE_CPU (sd, 0);
  cpu->cpu_configured_arch = arch;
  device_tree = sim_hw_parse (sd, "/");
  if (arch->arch == bfd_arch_m68hc11)
    {
      cpu->cpu_interpretor = cpu_interp_m6811;
      if (hw_tree_find_property (device_tree, "/m68hc11/reg") == 0)
	{
	  /* Allocate core managed memory */

	  /* the monitor  */
	  sim_do_commandf (sd, "memory region 0x%lx@%d,0x%lx",
			   /* MONITOR_BASE, MONITOR_SIZE */
			   0x8000, M6811_RAM_LEVEL, 0x8000);
	  sim_do_commandf (sd, "memory region 0x000@%d,0x8000",
			   M6811_RAM_LEVEL);
	  sim_hw_parse (sd, "/m68hc11/reg 0x1000 0x03F");
          if (cpu->bank_start < cpu->bank_end)
            {
              sim_do_commandf (sd, "memory region 0x%lx@%d,0x100000",
                               cpu->bank_virtual, M6811_RAM_LEVEL);
              sim_hw_parse (sd, "/m68hc11/use_bank 1");
            }
	}
      if (cpu->cpu_start_mode)
        {
          sim_hw_parse (sd, "/m68hc11/mode %s", cpu->cpu_start_mode);
        }
      if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11sio/reg") == 0)
	{
	  sim_hw_parse (sd, "/m68hc11/m68hc11sio/reg 0x2b 0x5");
	  sim_hw_parse (sd, "/m68hc11/m68hc11sio/backend stdio");
	  sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11sio");
	}
      if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11tim/reg") == 0)
	{
	  /* M68hc11 Timer configuration. */
	  sim_hw_parse (sd, "/m68hc11/m68hc11tim/reg 0x1b 0x5");
	  sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11tim");
          sim_hw_parse (sd, "/m68hc11 > capture capture /m68hc11/m68hc11tim");
	}

      /* Create the SPI device.  */
      if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11spi/reg") == 0)
	{
	  sim_hw_parse (sd, "/m68hc11/m68hc11spi/reg 0x28 0x3");
	  sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11spi");
	}
      if (hw_tree_find_property (device_tree, "/m68hc11/nvram/reg") == 0)
	{
	  /* M68hc11 persistent ram configuration. */
	  sim_hw_parse (sd, "/m68hc11/nvram/reg 0x0 256");
	  sim_hw_parse (sd, "/m68hc11/nvram/file m68hc11.ram");
	  sim_hw_parse (sd, "/m68hc11/nvram/mode save-modified");
	  /*sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/pram"); */
	}
      if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11eepr/reg") == 0)
	{
	  sim_hw_parse (sd, "/m68hc11/m68hc11eepr/reg 0xb000 512");
	  sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11eepr");
	}
      sim_hw_parse (sd, "/m68hc11 > port-a cpu-write-port /m68hc11");
      sim_hw_parse (sd, "/m68hc11 > port-b cpu-write-port /m68hc11");
      sim_hw_parse (sd, "/m68hc11 > port-c cpu-write-port /m68hc11");
      sim_hw_parse (sd, "/m68hc11 > port-d cpu-write-port /m68hc11");
      cpu->hw_cpu = sim_hw_parse (sd, "/m68hc11");
    }
  else
    {
      cpu->cpu_interpretor = cpu_interp_m6812;
      if (hw_tree_find_property (device_tree, "/m68hc12/reg") == 0)
	{
	  /* Allocate core external memory.  */
	  sim_do_commandf (sd, "memory region 0x%lx@%d,0x%lx",
			   0x8000, M6811_RAM_LEVEL, 0x8000);
	  sim_do_commandf (sd, "memory region 0x000@%d,0x8000",
			   M6811_RAM_LEVEL);
          if (cpu->bank_start < cpu->bank_end)
            {
              sim_do_commandf (sd, "memory region 0x%lx@%d,0x100000",
                               cpu->bank_virtual, M6811_RAM_LEVEL);
              sim_hw_parse (sd, "/m68hc12/use_bank 1");
            }
	  sim_hw_parse (sd, "/m68hc12/reg 0x0 0x3FF");
	}

      if (!hw_tree_find_property (device_tree, "/m68hc12/m68hc12sio@1/reg"))
	{
	  sim_hw_parse (sd, "/m68hc12/m68hc12sio@1/reg 0xC0 0x8");
	  sim_hw_parse (sd, "/m68hc12/m68hc12sio@1/backend stdio");
	  sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12sio@1");
	}
      if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12tim/reg") == 0)
	{
	  /* M68hc11 Timer configuration. */
	  sim_hw_parse (sd, "/m68hc12/m68hc12tim/reg 0x1b 0x5");
	  sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12tim");
          sim_hw_parse (sd, "/m68hc12 > capture capture /m68hc12/m68hc12tim");
	}

      /* Create the SPI device.  */
      if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12spi/reg") == 0)
	{
	  sim_hw_parse (sd, "/m68hc12/m68hc12spi/reg 0x28 0x3");
	  sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12spi");
	}
      if (hw_tree_find_property (device_tree, "/m68hc12/nvram/reg") == 0)
	{
	  /* M68hc11 persistent ram configuration. */
	  sim_hw_parse (sd, "/m68hc12/nvram/reg 0x2000 8192");
	  sim_hw_parse (sd, "/m68hc12/nvram/file m68hc12.ram");
	  sim_hw_parse (sd, "/m68hc12/nvram/mode save-modified");
	}
      if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12eepr/reg") == 0)
	{
	  sim_hw_parse (sd, "/m68hc12/m68hc12eepr/reg 0x0800 2048");
	  sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12eepr");
	}

      sim_hw_parse (sd, "/m68hc12 > port-a cpu-write-port /m68hc12");
      sim_hw_parse (sd, "/m68hc12 > port-b cpu-write-port /m68hc12");
      sim_hw_parse (sd, "/m68hc12 > port-c cpu-write-port /m68hc12");
      sim_hw_parse (sd, "/m68hc12 > port-d cpu-write-port /m68hc12");
      cpu->hw_cpu = sim_hw_parse (sd, "/m68hc12");
    }
  return 1;
}

/* Get the memory bank parameters by looking at the global symbols
   defined by the linker.  */
static int
sim_get_bank_parameters (SIM_DESC sd, bfd* abfd)
{
  sim_cpu *cpu;
  long symsize;
  long symbol_count, i;
  unsigned size;
  asymbol** asymbols;
  asymbol** current;

  cpu = STATE_CPU (sd, 0);

  symsize = bfd_get_symtab_upper_bound (abfd);
  if (symsize < 0)
    {
      sim_io_eprintf (sd, "Cannot read symbols of program");
      return 0;
    }
  asymbols = (asymbol **) xmalloc (symsize);
  symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
  if (symbol_count < 0)
    {
      sim_io_eprintf (sd, "Cannot read symbols of program");
      return 0;
    }

  size = 0;
  for (i = 0, current = asymbols; i < symbol_count; i++, current++)
    {
      const char* name = bfd_asymbol_name (*current);

      if (strcmp (name, BFD_M68HC11_BANK_START_NAME) == 0)
        {
          cpu->bank_start = bfd_asymbol_value (*current);
        }
      else if (strcmp (name, BFD_M68HC11_BANK_SIZE_NAME) == 0)
        {
          size = bfd_asymbol_value (*current);
        }
      else if (strcmp (name, BFD_M68HC11_BANK_VIRTUAL_NAME) == 0)
        {
          cpu->bank_virtual = bfd_asymbol_value (*current);
        }
    }
  free (asymbols);

  cpu->bank_end = cpu->bank_start + size;
  cpu->bank_shift = 0;
  for (; size > 1; size >>= 1)
    cpu->bank_shift++;

  return 0;
}

static int
sim_prepare_for_program (SIM_DESC sd, bfd* abfd)
{
  sim_cpu *cpu;
  int elf_flags = 0;

  cpu = STATE_CPU (sd, 0);

  if (abfd != NULL)
    {
      asection *s;

      if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
        elf_flags = elf_elfheader (abfd)->e_flags;

      cpu->cpu_elf_start = bfd_get_start_address (abfd);
      /* See if any section sets the reset address */
      cpu->cpu_use_elf_start = 1;
      for (s = abfd->sections; s && cpu->cpu_use_elf_start; s = s->next) 
        {
          if (s->flags & SEC_LOAD)
            {
              bfd_size_type size;

              size = bfd_get_section_size (s);
              if (size > 0)
                {
                  bfd_vma lma;

                  if (STATE_LOAD_AT_LMA_P (sd))
                    lma = bfd_section_lma (abfd, s);
                  else
                    lma = bfd_section_vma (abfd, s);

                  if (lma <= 0xFFFE && lma+size >= 0x10000)
                    cpu->cpu_use_elf_start = 0;
                }
            }
        }

      if (elf_flags & E_M68HC12_BANKS)
        {
          if (sim_get_bank_parameters (sd, abfd) != 0)
            sim_io_eprintf (sd, "Memory bank parameters are not initialized\n");
        }
    }

  if (!sim_hw_configure (sd))
    return SIM_RC_FAIL;

  /* reset all state information */
  sim_board_reset (sd);

  return SIM_RC_OK;
}

SIM_DESC
sim_open (SIM_OPEN_KIND kind, host_callback *callback,
          bfd *abfd, char **argv)
{
  SIM_DESC sd;
  sim_cpu *cpu;

  sd = sim_state_alloc (kind, callback);
  cpu = STATE_CPU (sd, 0);

  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);

  /* for compatibility */
  current_alignment = NONSTRICT_ALIGNMENT;
  current_target_byte_order = BIG_ENDIAN;

  cpu_initialize (sd, cpu);

  if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
    {
      free_state (sd);
      return 0;
    }

  /* getopt will print the error message so we just have to exit if this fails.
     FIXME: Hmmm...  in the case of gdb we need getopt to call
     print_filtered.  */
  if (sim_parse_args (sd, argv) != SIM_RC_OK)
    {
      /* Uninstall the modules to avoid memory leaks,
         file descriptor leaks, etc.  */
      free_state (sd);
      return 0;
    }

  /* Check for/establish the a reference program image.  */
  if (sim_analyze_program (sd,
			   (STATE_PROG_ARGV (sd) != NULL
			    ? *STATE_PROG_ARGV (sd)
			    : NULL), abfd) != SIM_RC_OK)
    {
      free_state (sd);
      return 0;
    }

  /* Establish any remaining configuration options.  */
  if (sim_config (sd) != SIM_RC_OK)
    {
      free_state (sd);
      return 0;
    }

  if (sim_post_argv_init (sd) != SIM_RC_OK)
    {
      /* Uninstall the modules to avoid memory leaks,
         file descriptor leaks, etc.  */
      free_state (sd);
      return 0;
    }
  if (sim_prepare_for_program (sd, abfd) != SIM_RC_OK)
    {
      free_state (sd);
      return 0;
    }      

  /* Fudge our descriptor.  */
  return sd;
}


void
sim_close (SIM_DESC sd, int quitting)
{
  /* shut down modules */
  sim_module_uninstall (sd);

  /* Ensure that any resources allocated through the callback
     mechanism are released: */
  sim_io_shutdown (sd);

  /* FIXME - free SD */
  sim_state_free (sd);
  return;
}

void
sim_set_profile (int n)
{
}

void
sim_set_profile_size (int n)
{
}

/* Generic implementation of sim_engine_run that works within the
   sim_engine setjmp/longjmp framework. */

void
sim_engine_run (SIM_DESC sd,
                int next_cpu_nr,	/* ignore */
		int nr_cpus,	/* ignore */
		int siggnal)	/* ignore */
{
  sim_cpu *cpu;

  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
  cpu = STATE_CPU (sd, 0);
  while (1)
    {
      cpu_single_step (cpu);

      /* process any events */
      if (sim_events_tickn (sd, cpu->cpu_current_cycle))
	{
	  sim_events_process (sd);
	}
    }
}

int
sim_trace (SIM_DESC sd)
{
  sim_resume (sd, 0, 0);
  return 1;
}

void
sim_info (SIM_DESC sd, int verbose)
{
  const char *cpu_type;
  const struct bfd_arch_info *arch;

  /* Nothing to do if there is no verbose flag set.  */
  if (verbose == 0 && STATE_VERBOSE_P (sd) == 0)
    return;

  arch = STATE_ARCHITECTURE (sd);
  if (arch->arch == bfd_arch_m68hc11)
    cpu_type = "68HC11";
  else
    cpu_type = "68HC12";

  sim_io_eprintf (sd, "Simulator info:\n");
  sim_io_eprintf (sd, "  CPU Motorola %s\n", cpu_type);
  sim_get_info (sd, 0);
  sim_module_info (sd, verbose || STATE_VERBOSE_P (sd));
}

SIM_RC
sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
                     char **argv, char **env)
{
  return sim_prepare_for_program (sd, abfd);
}


void
sim_set_callbacks (host_callback *p)
{
  /*  m6811_callback = p; */
}


int
sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
{
  sim_cpu *cpu;
  uint16 val;
  int size = 2;

  cpu = STATE_CPU (sd, 0);
  switch (rn)
    {
    case A_REGNUM:
      val = cpu_get_a (cpu);
      size = 1;
      break;

    case B_REGNUM:
      val = cpu_get_b (cpu);
      size = 1;
      break;

    case D_REGNUM:
      val = cpu_get_d (cpu);
      break;

    case X_REGNUM:
      val = cpu_get_x (cpu);
      break;

    case Y_REGNUM:
      val = cpu_get_y (cpu);
      break;

    case SP_REGNUM:
      val = cpu_get_sp (cpu);
      break;

    case PC_REGNUM:
      val = cpu_get_pc (cpu);
      break;

    case PSW_REGNUM:
      val = cpu_get_ccr (cpu);
      size = 1;
      break;

    case PAGE_REGNUM:
      val = cpu_get_page (cpu);
      size = 1;
      break;

    default:
      val = 0;
      break;
    }
  if (size == 1)
    {
      memory[0] = val;
    }
  else
    {
      memory[0] = val >> 8;
      memory[1] = val & 0x0FF;
    }
  return size;
}

int
sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
{
  uint16 val;
  sim_cpu *cpu;

  cpu = STATE_CPU (sd, 0);

  val = *memory++;
  if (length == 2)
    val = (val << 8) | *memory;

  switch (rn)
    {
    case D_REGNUM:
      cpu_set_d (cpu, val);
      break;

    case A_REGNUM:
      cpu_set_a (cpu, val);
      return 1;

    case B_REGNUM:
      cpu_set_b (cpu, val);
      return 1;

    case X_REGNUM:
      cpu_set_x (cpu, val);
      break;

    case Y_REGNUM:
      cpu_set_y (cpu, val);
      break;

    case SP_REGNUM:
      cpu_set_sp (cpu, val);
      break;

    case PC_REGNUM:
      cpu_set_pc (cpu, val);
      break;

    case PSW_REGNUM:
      cpu_set_ccr (cpu, val);
      return 1;

    case PAGE_REGNUM:
      cpu_set_page (cpu, val);
      return 1;

    default:
      break;
    }

  return 2;
}

void
sim_size (int s)
{
  ;
}

/* Halt the simulator after just one instruction */

static void
has_stepped (SIM_DESC sd,
	     void *data)
{
  ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
  sim_engine_halt (sd, NULL, NULL, NULL_CIA, sim_stopped, SIM_SIGTRAP);
}


/* Generic resume - assumes the existance of sim_engine_run */

void
sim_resume (SIM_DESC sd,
	    int step,
	    int siggnal)
{
  sim_engine *engine = STATE_ENGINE (sd);
  jmp_buf buf;
  int jmpval;

  ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);

  /* we only want to be single stepping the simulator once */
  if (engine->stepper != NULL)
    {
      sim_events_deschedule (sd, engine->stepper);
      engine->stepper = NULL;
    }
  sim_module_resume (sd);

  /* run/resume the simulator */
  engine->jmpbuf = &buf;
  jmpval = setjmp (buf);
  if (jmpval == sim_engine_start_jmpval
      || jmpval == sim_engine_restart_jmpval)
    {
      int last_cpu_nr = sim_engine_last_cpu_nr (sd);
      int next_cpu_nr = sim_engine_next_cpu_nr (sd);
      int nr_cpus = sim_engine_nr_cpus (sd);

      sim_events_preprocess (sd, last_cpu_nr >= nr_cpus, next_cpu_nr >= nr_cpus);
      if (next_cpu_nr >= nr_cpus)
	next_cpu_nr = 0;

      /* Only deliver the siggnal ]sic] the first time through - don't
         re-deliver any siggnal during a restart. */
      if (jmpval == sim_engine_restart_jmpval)
	siggnal = 0;

      /* Install the stepping event after having processed some
         pending events.  This is necessary for HC11/HC12 simulator
         because the tick counter is incremented by the number of cycles
         the instruction took.  Some pending ticks to process can still
         be recorded internally by the simulator and sim_events_preprocess
         will handle them.  If the stepping event is inserted before,
         these pending ticks will raise the event and the simulator will
         stop without having executed any instruction.  */
      if (step)
        engine->stepper = sim_events_schedule (sd, 0, has_stepped, sd);

#ifdef SIM_CPU_EXCEPTION_RESUME
      {
	sim_cpu* cpu = STATE_CPU (sd, next_cpu_nr);
	SIM_CPU_EXCEPTION_RESUME(sd, cpu, siggnal);
      }
#endif

      sim_engine_run (sd, next_cpu_nr, nr_cpus, siggnal);
    }
  engine->jmpbuf = NULL;

  sim_module_suspend (sd);
}
